c++ - 内联类函数和共享库 (dll) 构建

标签 c++ mingw shared-libraries inline dllexport

我正在尝试将一些代码移动到共享库中(在独立编译时工作正常)但遇到了类内联函数的一些问题。 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 conflict with inlining [-Winline]

使用 INLINE_OPTION == 3(尝试强制内联),我收到与上面相同的警告,并且我收到此错误:error: inlining failed in call to always_inline 'int Dummy::get_int() const' : 函数不可内联,有关它的信息是从 .cpp 文件中 Dummy::do_something() 的第一行调用的。请注意,这是关于尝试在库本身中内联函数!对于简单的访问器函数,这可能是非常重要的开销。

我做错了什么吗? gcc 以不同于类内函数定义的方式处理类外定义内联函数是否正确? (我真的被迫弄乱类声明吗?)

注意:该问题不仅仅影响我声明为内联的内容。当涉及继承时,它还会影响任何声明为 constexpr 甚至声明为“= default”的析构函数。

编辑:

刚刚尝试使用 mingw64/gcc v4.8.0,结果相同。请注意,这包括选项 1 未内联 do_something 的事实(我检查了汇编程序输出),因此显然选项 1 和选项 2 之间的唯一区别是只有选项 2 会给出 -Winline 警告。

最佳答案

我对如何在 Windows 上创建共享库一无所知。在 linux/OSX 中,源代码不需要特殊处理,因此共享 (.so) 和普通 (.a) 库都可以从相同的源代码中生成而无需特殊处理。

如果您确实需要将符号导出到共享库的特殊属性,那么您可以简单地拆分代码,例如

namespace implementation_details {
  class __attribute__((dllexport)) DummyBase
  {
  protected:
    DummyBase() : m_int{0} {}
    ~DummyBase() {}
    int do_something();
    int m_int;
  };
}

struct Dummy: private implementation_details::DummyBase
{
  using implementation_details::DummyBase::do_something;
  int get_int() const noexcept;
};

inline __attribute__((always_inline)) int Dummy::get_int() const noexcept
{ return m_int; }

关于c++ - 内联类函数和共享库 (dll) 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15676873/

相关文章:

c++ - 为什么 dependency walker 显示缺少的 dll?

c++ - Qt - 如何将 QProcess 的标准输出重定向到 TextEdit

c++ - 已部署的 C++ AMP 应用程序停止响应

将静态库转换为共享库?

shared-libraries - 如何在 Linux 上设置 LibGDX 的 fbx-conv

c++ - 在 DEBUG 模式下工作,但在 RELEASE 模式下失败

android - 在 100% C++ 环境中为 Android 编程?

c - 在 gdb 上,LoadLibrary 满足 sti 指令并发出 SIGILL 信号

opencv - opencv 2.4.5无法在Windows中正确加载tif图像文件

c - 以两种不同方式指向动态库的函数指针