MSVC:为啥包含基本 QString 操作的函数没有内联?

Posted

技术标签:

【中文标题】MSVC:为啥包含基本 QString 操作的函数没有内联?【英文标题】:MSVC: Why are functions containing basic QString operations not inlined?MSVC:为什么包含基本 QString 操作的函数没有内联? 【发布时间】:2015-12-17 09:59:06 【问题描述】:

使用 MSVC (full source) 编译此示例时

#include <QString>
#include <QDebug>

static __forceinline QString makeString() 
    return ;


int main()

    QString str = makeString();
    qDebug() << str;
    return 0;

发出以下警告:

function 'QString makeString(void)' marked as __forceinline not inlined

对于编译,我使用默认的 qmake 设置(加上 -W4 警告):

cl -c -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zc:throwingNew -O2 -MD -GR -W4 -EHsc
-w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4127 -w34100
-DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG
-IC:\home\dev\qstring_inline -I. -I..\..\qt\qt_5.5.1\build\qtbase\include -I..\..\qt\qt_5.5.1\build\qtbase\include\QtGui -I..\..\qt\qt_5.5.1\build\qtbase\include\QtCore -Irelease -Ie:\builds\qt\qt_5.5.1\qt5\qtbase\mkspecs\win32-msvc2015 -Forelease\ @C:\Users\ens\AppData\Local\Temp\main.obj.17344.16.jom
main.cc

我已经用Qt 5.5.1Qt 5.4VS 2015 Update 1, 64-bit MSVCVS 2013 Update 5, 64-bit MSVC 重现了这个问题。

检查程序集确认确实生成并调用了 makeString()。

都是默认构造函数(code browser)...

inline QString::QString() Q_DECL_NOTHROW : d(Data::sharedNull()) 

...和右值复制构造函数 (code browser)

inline QString(QString && other) Q_DECL_NOTHROW : d(other.d)  other.d = Data::sharedNull(); 

非常简单。 什么可以阻止 makeString() 被内联?

【问题讨论】:

您是否查看过 asm 以检查是否确实有对 makeString 的调用。也许调用被构造函数和 RVO 省略,但没有标记为 inlined 只是一个怀疑,但 sharedNull 事情最终会在 QArrayData 中使用静态字符数组 - 编译器可能不希望内联并且有很多地址到该数组以在链接处修补时间,或者加载时间,如果它最终位于共享对象中...... @Jarod42,是的,生成并调用了 makeString。我已将此添加到我的帖子中。 【参考方案1】:

编译器无法内联具有非平凡析构函数的返回类型的函数。这是编译器的限制;编译器团队正在考虑在未来的版本中对此进行改进。

【讨论】:

以上是关于MSVC:为啥包含基本 QString 操作的函数没有内联?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MSVC12 的自动矢量化器不分析函数模板?

为啥在 __assume 中使用函数调用时 MSVC 不报错?

为啥这个 MSVC asm 块没有 ret,或者非 void 函数有返回?

如何使用 msvc 2019 编译 QT 4 dll?

为啥 msvc 让我这样做而不是 gcc / g++?

QString与std::string 有中文时的转换操作