我正在尝试将一些代码移动到共享库中(独立编译时工作正常),但遇到类内联函数的一些问题。mingw/gcc v4.7.2。
部分问题似乎是因为我更喜欢在类声明之外定义我的内联函数(它使类声明更整洁,更易于阅读)。我一直认为这是可以接受的,并且等同于在类声明中定义......但似乎并非总是如此。我创建了一个简单的示例来演示这些问题。(显然 dllexport 通常会在一个宏中在导入/导出之间切换。)
标题:
// Uncomment one at a time to see how it compiles with: -O2 -Winline
//#define INLINE_OPTION 1 // implicit - builds without inline warnings
#define INLINE_OPTION 2 // simple external inline - gives inline warnings
//#define INLINE_OPTION 3 // external forced inline - gives inline errors
class __attribute__((dllexport)) Dummy {
public:
Dummy() : m_int{0} {}
~Dummy() {}
#if INLINE_OPTION == 1
int get_int() const { return m_int; }
#else
int get_int() const;
#endif
int do_something();
private:
int m_int;
};
#if INLINE_OPTION == 2
inline int Dummy::get_int() const
{ return m_int; }
#endif
#if INLINE_OPTION == 3
inline __attribute__((always_inline)) int Dummy::get_int() const
{ return m_int; }
#endif
.cpp 文件:
int Dummy::do_something()
{
int i = get_int();
i *= 2;
return i;
}
如上所述,使用 INLINE_OPTION == 1(隐式,类内内联定义)代码编译时没有警告。
使用 INLINE_OPTION == 2 (类外内联定义)我收到以下警告:int Dummy::get_int() const' can never be inlined because it uses attributes conflicting with inlining [-Winline]
使用 INLINE_OPTION == 3 (试图强制内联),我得到与上面相同的警告,并且我得到这个错误:error: inlining failed in call to always_inline 'int Dummy::get_int() const': function not inlinable
,有关它的信息是从 .cpp 文件中的 Dummy::do_something() 内的第一行调用的. 请注意,这是关于尝试在库本身内内联函数!对于简单的访问器函数,这可能是非常重要的开销。
难道我做错了什么?将类外定义内联函数与类内函数定义区别对待,gcc 是否正确?(我真的被迫弄乱类声明吗?)
注意:问题不仅仅影响我声明的内联内容。当涉及继承时,它还会影响任何声明为 constexpr 甚至声明为“= default”的析构函数。
编辑:
刚刚尝试使用 mingw64 / gcc v4.8.0 得到相同的结果。请注意,这包括选项 1 没有内联在 do_something 中的事实(我检查了汇编程序输出),因此显然选项 1 和选项 2 之间的唯一区别是只有选项 2 会给出 -Winline 警告。