如何在C ++中正确定义常量

时间:2017-07-18 07:44:16

标签: c++

我在许多C ++代码库中看到了一个共同的模式:

Header.h:

static const int myConstant = 1;

Source1.cpp:

#include "Header.h"

Source2.cpp:

#include "Header.h"

基于:

  

3.5计划和联系

...

  

(2.1) - 当一个名称有外部链接时,它所代表的实体可以通过范围中的名称来引用   其他翻译单位或同一翻译单位的其他范围。

     

(2.2) - 当名称具有内部链接时,其表示的实体可以通过其他范围的名称引用   在同一个翻译单元。

...

  

3具有命名空间范围(3.3.6)的名称具有内部链接(如果它是

的名称)      

(3.1) - 显式声明为static的变量,函数或函数模板;或者,

myConstant只能从同一个翻译单元访问,编译器会生成多个实例,每个翻译单元一个包含Header.h

我的理解是否正确 - 创建了myConstant的多个实例?如果是这种情况,请指点我在C ++中使用常量的更好的替代方案

编辑:

有些人建议在标题中添加myConstant extern,并在一个cpp文件中定义它。这是一个好习惯吗?我猜测这将使编译器看不到该值并阻止许多优化,例如当值出现在算术运算中时。

2 个答案:

答案 0 :(得分:4)

你正在做的事情应该没问题。优化器可能会避免为常量创建任何存储,而是将其替换为值的任何使用,只要您从不接受变量的地址(例如&myConstant)。

答案 1 :(得分:1)

头文件中出现的模式static const int myConstant = 1有点奇怪,因为关键字static将变量定义的范围限制在特定的翻译单元。因此,不能从其他翻译单元访问该变量。所以我不明白为什么有人可能会在头文件中公开一个变量,尽管这个变量永远不能从“外部”解决。

请注意,如果不同的翻译单元包含标题,那么每个翻译单元都会定义自己的,这个变量的某种“私有”实例。

我认为共同的模式应该是:

在头文件中:

extern const int myConstant;

在整个程序的一个实现文件中:

const int myConstant = 1;

然而,评论说,这将阻止编译器进行优化,因为在编译翻译单元时不知道常量的值(这听起来很合理)。

所以似乎“全局/共享”常量是不可能的,并且可能必须在头文件中使用 - 有点矛盾 - 关键字static

此外,我使用constexr来表示编译时常量(尽管编译器可能会得到这个):

 static constexpr int x = 1;

由于static - 关键字仍然以某种方式扰乱了我,我在constexpr上进行了一些研究和实验,没有static关键字但使用extern关键字。不幸的是,extern constexpr仍然需要初始化(这使得它成为一个定义,并导致重复的符号错误)。有趣的是,至少在我的编译器中,我实际上可以在不同的转换单元中定义constexpr int x = 1而不会引入编译器/链接器错误。但我没有在标准中找到对此行为的支持。但是在头文件中定义constexpr int x = 1static constexpr int x = 1更加好奇。

所以 - 很多单词,很少有发现。我认为static constexpr int x = 1是最好的选择。