为什么在C ++中而不是在C中允许使用const全局变量的多个定义?
由于One Definition Rule,C或C ++中不允许对全局变量进行多重定义。 但是,在C ++中,const全局变量可以在多个编译单元中定义而没有错误。 这跟C中的不一样。
为什么C ++允许这样做而C不允许? 与C相比,为什么const全局的使用和行为在C ++中以这种方式与非const全局不同? C ++和C关于const的内容正在发生什么?
例如,这在C ++中是允许的,但在C中是错误的:
// Foo.cpp const int Foo = 99; // Main.cpp const int Foo = 99; int main() { cout << Foo << endl; return 0; }
这对C来说很好,但C ++有问题:
// Foo.cpp const int Foo = 99; // Main.cpp extern const int Foo; int main() { cout << Foo << endl; return 0; }
// Foo.cpp const int Foo = 99; // Main.cpp const int Foo = 99;
命名空间范围内的 const
变量具有内部链接。 所以它们基本上是两个不同的变量。 没有重新定义。
来自@ David的评论,3.5 / 3 [basic.link]:
具有命名空间范围(3.3.5)的名称具有内部链接(如果它的名称)
– 明确声明为静态的对象,引用,函数或函数模板,或
– 显式声明为const的对象或引用, 既未显式声明为extern,也未声明为具有外部链接 ; 要么
– 匿名联盟的数据成员。
在第二种情况下,你应该这样做(正确的方式):
//Foo.h extern const int Foo; //use extern here to make it have external linkage! // Foo.cpp #include "Foo.h" const int Foo = 99; //actual definition goes here // Main.cpp #include "Foo.h" int main() { cout << Foo << endl; }
我认为你要求的理由而不是具体的语言规则。
这样做的理由是它使const
变量更容易使用。 它为#define
一个常见用途提供了类型替换。
您可以使用const int max_count = 211;
而不是#define MAX_COUNT 211
const int max_count = 211;
以完全相同的方式,例如共享头文件,而不必担心放置一个定义的位置。
您不能合法地更改const
对象的值,因此在一个对象和具有相同值的多个对象之间没有明显的区别。
由于您可以在头文件中定义const
对象,因此编译器可以直接在编译阶段使用该值,而不必将此类优化延迟到链接时修复。
基本上,在C ++中,const,非局部变量是真正的常量表达式,或constexpr。 这允许很多东西,比如TMP。
const int five = 5; int main() { int x[five]; std::array arr; }
在C中,它们只是一个无法修改的变量。 那是,
const int five = 5; int main() { int x[five]; // Technically, this is a variable length array }
相当于
int five = 5; int main() { int x[five]; }
实际上,C ++将某些const
变量提升为新类别constexpr
,而在C中,这不存在,它们只是碰巧不可修改的变量。
看起来const 实际上并不生成外部符号 。
为什么英国人拼写COLOR,而美国人拼写COLOR?
它们是来自同一基础的两种不同语言,但它们没有相同的规则。
C&C ++是一样的。 如果他们没有什么不同,他们都会被称为同一件事。
我的解决方法是将其声明为:
static classfoo foo;
它适用于我的情况。