Linux gcc和Windows Visual Studio处理静态常量的区别
Difference between Linux gcc and Windows Visual Studio handling of static constants?
我们一直在Linux(gcc)和Windows(Visual Studio)上编译一个库,正如预期的那样,在这两个平台上获得干净编译所需的内容之间存在微小但不显著的差异。
今天,我将gcc编译器标志更改为使用-fPIC
(以便能够创建共享库)。当我们针对库测试链接程序时,我们开始出现错误(第一次),undefined reference
到2个静态常量在头文件中声明和初始化(但不在.cpp文件中)。
我找到了这个StackOverflow的答案,它似乎解决了这个问题,解释说,即使static const
在头文件中初始化,它仍然需要在代码文件中定义。进行该更改确实删除了gcc链接器错误。
然而,Visual Studio不喜欢这种更改,并生成了multiple definition
错误。我们必须包装需要一个预处理器条件的定义,以使Visual Studio能够干净地编译。
有人能告诉我这里有什么不同吗?(代码摘录如下。)
消息.h
class msg
{
public:
static const int EMPTY_INT_VALUE = INT_MAX;
static const char EMPTY_STRING_VALUE = ' 02';
// can't define value in header, defined in cpp file
static const double EMPTY_DOUBLE_VALUE;
...
}
消息.cpp
#include "msg.h"
const double msg::EMPTY_DOUBLE_VALUE(DBL_MAX);
#ifndef _WIN32
// g++ requires these definitions, vs 2010 doesn't like them
const int msg::EMPTY_INT_VALUE;
const char msg::EMPTY_STRING_VALUE;
#endif
我已经追踪到C++语言规范(INCITS/ISO/IEC 14882-2011[2012])第9.4.2节"静态数据成员":
如果非易失性
const static
数据成员是整型或枚举型,则其在类定义中的声明可以指定大括号或相等初始化器,其中作为赋值表达式的每个初始化器子句都是常量表达式(5.19)。文本类型的static
数据成员可以在类定义中将constexpr
说明符声明;如果是,则其声明应指定大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定子句都是常量表达式。[注意:在这两种情况下,成员都可能出现在常量表达式中。--结束注释]如果在程序中使用odr(3.2),则该成员仍应在命名空间范围中定义,并且命名空间范围定义不应包含初始值设定项。
因此,对于积分类型(例如,示例中的int
和char
),可以在类定义中初始化。如果这样做,还必须在命名空间范围内(即在.cpp
文件中)定义它,并且不带初始值设定项。在规范的其他部分中,声明了static
数据成员在其类中的声明是而不是定义,因此必须伴随着命名空间范围的定义,这就是您在示例中所做的。
GCC遵循规范的这一部分,而Visual C++则没有。我使用Visual Studio 2012进行了测试。
以下是另一个关于Visual C++在这方面的不合规性的讨论。这里描述的解决方法正是您正在做的:保护积分变量的定义,尽管它们使用的是_MSC_VER
。
- 私有类型的静态常量成员
- 分离一个静态常量 std::thread?
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 我可以在运行时重新定义在 OpenCascade/OCCT 标头中定义的 c++ 静态常量吗?
- 如何为静态常量模板化专用整数值分配存储
- 使用什么代替"静态常量 TCHAR *"
- C++ 模板中的静态常量初始化顺序
- 如何在编译时解析静态常量 std::string?
- 关于静态常量数据模因的声明和定义的混淆
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- 为什么在第二类中使用静态常量会在第一类中给出编译器错误?
- 静态常量与常量局部变量,哪一个性能更好
- 如何在模板类中设置静态常量变量
- public:静态常量字符串声明/初始化问题
- 有没有办法声明一个公共静态常量,该常量将使用 constexpr 在源文件中定义(有什么区别)?
- 对静态常量积分类型的未定义引用
- 全局变量中的静态常量与常量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 避免在静态常量类上定义但不使用
- 指向静态常量对象的共享指针?