*.cpp 文件中实现的 c++ functions/methods 永远不会内联扩展吗?
Will c++ functions/methods implemented in *.cpp file be NEVER inline expanded?
关于"inline"在c++中已经有很多很好的解释了,比如this and this...
但一般来说大部分都在谈论"even though a func with inline prefix, may or may not be expanded",
或大约 "it's up to the compiler...".
当我最近重构我的旧代码时,我需要决定是保留还是移动一些内联 functions/methods 到确定的文件(而不是 header 文件)。
所以我需要知道 "If a func/method(without inline prefix) be implemented in *.cpp file instead of header file, may it NEVER be inline/expanded?"。
如果我们让它们保持在 header 秒内,至少会有一个 chance/hope 它们会被内联?
请原谅我丑陋的英语,这不是我的主要语言。
Will c++ functions/methods implemented in *.cpp file be NEVER inline expanded?
这是一个实现问题,特定于您的 特定 C++ 编译器。
如果您最近使用 GCC as your C++ compiler, you could be interested by compiler flags such as -Wall -O0 -fno-inline
(or, on the opposite, optimizing with -flto -fwhole-program -Wall -O3
both at compile and link time). Configure wisely your build automation 工具(例如您的 Makefile
)。
但生成的可执行文件可能 运行 较慢。
我在 2020 年 5 月使用(例如,在 RefPerSys) g++ -fno-inline -O0 -g3
with GCC 9 or GCC 10 for ease of debugging with GDB (on Linux/Debian/Sid/x86-64). The same C++ source code can be compiled twice in two different ELF executables, one with full DWARF 信息中并且没有内联,另一个带有 DWARF 信息和优化标志。
When I am refactoring my old codes recently, I need to decide whether keep or move some inline functions/methods into definite file (instead of header file).
这样做的唯一合理原因是减少编译时间。这是一个真正的问题吗? 您需要多少小时来编译您的 C++ 代码?您还可以要求您的经理或客户为您购买功能更强大的开发计算机。在 Workplace 上寻求指导并提供法律细节。
一种可能是在调试阶段使用 g++ -Wall -Wextra -O0 -fno-inline -g
进行编译,并交付使用 g++ -Wall -Wextra -O3 -flto
编译和链接的相同 C++ 代码用于生产目的。如果担心可执行文件的大小,请考虑将 -O3
替换为 -Os
。 YMMV.
还要考虑法律方面的考虑,请参阅 this。
当然多读书about C++.
我想到了 n3337 C++11 标准。
关于内联,您可以使用 g++ -S -fverbose-asm -O3
进行编译,如果发生内联,则查看生成的代码。您甚至可以编写自己的 GCC plugin to drive inlining decisions (see the GCC MILEPOST project or the old GCC MELT one or Bismon)。这需要几个月的全职工作。
PS。我碰巧从事 Bismon 的专业工作,并为 GCC 做出了贡献。请随时通过电子邮件与我联系 basile.starynkevitch@cea.fr
。也许我的老板会因为一份关于它的合同(仅超过 5 万欧元)而感到高兴。决定权不是我的,而是我的雇主 CEA LIST (and then political considerations matter regarding policies between France -near Paris- where I work and live and China -near Singapore- 你工作的地方)。
请记住,在 C++(和 C)中,编译器使用的是一个 translation unit,,其中 - 在预处理之后 - 来自 .cpp
文件的行和来自 .cpp
文件的行之间没有区别一个 header (.h
/.hpp
/.hxx
) 文件。因此,在包含函数的 definition 的翻译单元中 - 没有任何变化。内联也是有可能的。
其他翻译单元怎么办,以前只能看到函数的定义,现在只能看到函数的声明?这里,主要问题是:"Does my compiler and linker support link-time optimization?" 如果您的编译器不支持 LTO,或者您没有启用 LTO 支持 - 那么,通常,您的函数不会内联。如果支持并启用 LTO,则链接器具有 "deeper" 信息,允许它重新排列 already-compiled 函数,以便从不同的已编译 object 中插入另一个此类函数的代码。因此,使用 LTO,您的 .cpp
定义的函数可能仍会内联 。但它可能比编译期间更不可能。
关于"inline"在c++中已经有很多很好的解释了,比如this and this...
但一般来说大部分都在谈论"even though a func with inline prefix, may or may not be expanded", 或大约 "it's up to the compiler...".
当我最近重构我的旧代码时,我需要决定是保留还是移动一些内联 functions/methods 到确定的文件(而不是 header 文件)。 所以我需要知道 "If a func/method(without inline prefix) be implemented in *.cpp file instead of header file, may it NEVER be inline/expanded?"。 如果我们让它们保持在 header 秒内,至少会有一个 chance/hope 它们会被内联?
请原谅我丑陋的英语,这不是我的主要语言。
Will c++ functions/methods implemented in *.cpp file be NEVER inline expanded?
这是一个实现问题,特定于您的 特定 C++ 编译器。
如果您最近使用 GCC as your C++ compiler, you could be interested by compiler flags such as -Wall -O0 -fno-inline
(or, on the opposite, optimizing with -flto -fwhole-program -Wall -O3
both at compile and link time). Configure wisely your build automation 工具(例如您的 Makefile
)。
但生成的可执行文件可能 运行 较慢。
我在 2020 年 5 月使用(例如,在 RefPerSys) g++ -fno-inline -O0 -g3
with GCC 9 or GCC 10 for ease of debugging with GDB (on Linux/Debian/Sid/x86-64). The same C++ source code can be compiled twice in two different ELF executables, one with full DWARF 信息中并且没有内联,另一个带有 DWARF 信息和优化标志。
When I am refactoring my old codes recently, I need to decide whether keep or move some inline functions/methods into definite file (instead of header file).
这样做的唯一合理原因是减少编译时间。这是一个真正的问题吗? 您需要多少小时来编译您的 C++ 代码?您还可以要求您的经理或客户为您购买功能更强大的开发计算机。在 Workplace 上寻求指导并提供法律细节。
一种可能是在调试阶段使用 g++ -Wall -Wextra -O0 -fno-inline -g
进行编译,并交付使用 g++ -Wall -Wextra -O3 -flto
编译和链接的相同 C++ 代码用于生产目的。如果担心可执行文件的大小,请考虑将 -O3
替换为 -Os
。 YMMV.
还要考虑法律方面的考虑,请参阅 this。
当然多读书about C++.
我想到了 n3337 C++11 标准。
关于内联,您可以使用 g++ -S -fverbose-asm -O3
进行编译,如果发生内联,则查看生成的代码。您甚至可以编写自己的 GCC plugin to drive inlining decisions (see the GCC MILEPOST project or the old GCC MELT one or Bismon)。这需要几个月的全职工作。
PS。我碰巧从事 Bismon 的专业工作,并为 GCC 做出了贡献。请随时通过电子邮件与我联系 basile.starynkevitch@cea.fr
。也许我的老板会因为一份关于它的合同(仅超过 5 万欧元)而感到高兴。决定权不是我的,而是我的雇主 CEA LIST (and then political considerations matter regarding policies between France -near Paris- where I work and live and China -near Singapore- 你工作的地方)。
请记住,在 C++(和 C)中,编译器使用的是一个 translation unit,,其中 - 在预处理之后 - 来自 .cpp
文件的行和来自 .cpp
文件的行之间没有区别一个 header (.h
/.hpp
/.hxx
) 文件。因此,在包含函数的 definition 的翻译单元中 - 没有任何变化。内联也是有可能的。
其他翻译单元怎么办,以前只能看到函数的定义,现在只能看到函数的声明?这里,主要问题是:"Does my compiler and linker support link-time optimization?" 如果您的编译器不支持 LTO,或者您没有启用 LTO 支持 - 那么,通常,您的函数不会内联。如果支持并启用 LTO,则链接器具有 "deeper" 信息,允许它重新排列 already-compiled 函数,以便从不同的已编译 object 中插入另一个此类函数的代码。因此,使用 LTO,您的 .cpp
定义的函数可能仍会内联 。但它可能比编译期间更不可能。