在VS2008和GCC中编译静态const int = X的最佳代码

时间:2011-08-31 21:08:16

标签: c++ visual-c++ gcc cross-platform

我在编写需要在Visual Studio 2008和GCC 4.6中编译的C ++代码时遇到了问题(并且还需要编译回GCC 3.4):static const int类成员。

Other questions have covered静态const int类成员所需的规则。特别是,标准和GCC要求变量在一个且只有一个目标文件中具有定义。

但是,Visual Studio在编译包含.cpp文件中的定义的代码(在调试模式下)时会创建LNK2005错误。

我试图决定的一些方法是:

  • 使用.cpp文件中的值初始化它,而不是标题。
  • 使用预处理器删除MSVC的定义。
  • 将其替换为枚举。
  • 用宏替换它。

最后两个选项没有吸引力,我可能不会使用任何一个。第一个选项很简单 - 但我喜欢在标题中有值。

我在答案中寻找的是一个好看的最佳实践方法,用于构建代码以使GCC和MSVC同时满意。我希望有一些奇妙的美丽,我还没有想到。

4 个答案:

答案 0 :(得分:3)

我通常更喜欢 enum 方式,因为这可以保证它始终用作立即值而不会获得任何存储空间。它被编译器识别为常量表达式。

class Whatever {
    enum { // ANONYMOUS!!!
        value = 42;
    };
    ...
}

如果你不能这样做,#ifdef远离MSVC的.cpp 中的定义,因为如果你在声明中取消了该值,它将始终获得存储;编译器不知道该值,因此它不能内联它(好吧,“链接时间代码生成”应该能够在启用时修复它)并且不能在需要常量的地方使用它,如值模板参数或数组大小。

答案 1 :(得分:2)

如果你不喜欢使用非标准黑客的想法,对VC ++来说总是__declspec(selectany)。我的理解是,它将确保在链接时,通过删除除一个定义之外的所有冲突来解决任何冲突。您可以将其放在#ifdef _MSC_VER块中。

答案 2 :(得分:1)

Visual C ++ 2010接受此:

// test.hpp:
struct test {
    static const int value;
};

// test.cpp:
#include "test.hpp"
const int test::value = 10;

答案 3 :(得分:0)

这仍然是VS2013的一个问题。我通过在cpp文件中将符合标准的定义放在防止VS的#if中来解决这个问题。

A.H:

class A
{
public:
  static unsigned const a = 10;
};

a.cpp:

#ifndef _MSC_VER
unsigned const A::a;
#endif

我也很好地评论了它,所以文件中的下一个人知道应该责怪哪个编译器。