[英]Why is multiple definition of a const global variable allowed in C++ and not in C?
Multiple definition of a global variable is not allowed in C or C++ due to the One Definition Rule.由于单一定义规则,在 C 或 C++ 中不允许对全局变量进行多重定义。 However, in C++ a const global variable can be defined in multiple compilation units with no error.
但是,在 C++ 中,可以在多个编译单元中定义 const 全局变量而不会出错。 This is not the same as in C.
这与 C 中的不同。
Why does C++ allow this while C does not?为什么 C++ 允许这样做,而 C 不允许? Why does the usage and behaviour of a const global differ from a non-const global in this way in C++ compared to C?
与 C 相比,为什么在 C++ 中 const 全局的用法和行为与非 const 全局不同? What is happening under the covers with C++ and C with respect to const?
C++ 和 C 在 const 方面发生了什么?
For example this is allowed in C++, but wrong in C:例如,这在 C++ 中是允许的,但在 C 中是错误的:
// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
int main()
{
cout << Foo << endl;
return 0;
}
And this is fine with C, but wrong with C++:这对 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
variable at namespace scope has internal linkage.命名空间 scope 的
const
变量具有内部链接。 So they're basically two different variables.所以它们基本上是两个不同的变量。 There is no redefinition.
没有重新定义。
From @David's comment, 3.5/3 [basic.link]:来自@David 的评论,3.5/3 [basic.link]:
A name having namespace scope (3.3.5) has internal linkage if it is the name of
具有命名空间scope (3.3.5) 的名称如果是
— an object, reference, function or function template that is explicitly declared static or,— 一个 object,参考,function 或 function 模板,明确声明 ZA81259CEF48E959C6297EDF1 或 3
— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage ;— 一个 object 或显式声明为 const 且既未显式声明 extern 也未先前声明具有外部链接的引用; or
或者
— a data member of an anonymous union.— 匿名工会的数据成员。
In the second case, you should be doing this (correct way):在第二种情况下,您应该这样做(正确的方法):
//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;
}
I think you are asking for the rationale and not the specific language rule that allows this.我认为您要的是基本原理,而不是允许这样做的特定语言规则。
The rationale for this is that it makes const
variables much easier to use.这样做的理由是它使
const
变量更容易使用。 It gives a typed replacement for one common use of #define
.它为
#define
的一种常见用法提供了类型化替换。
Instead of #define MAX_COUNT 211
you can use const int max_count = 211;
您可以使用
#define MAX_COUNT 211
而不是const int max_count = 211;
in exactly the same way, eg a shared header file, without having to worry about where to put the one definition.以完全相同的方式,例如共享 header 文件,而不必担心将一个定义放在哪里。
You can't legally change the value of a const
object so there's no visible difference between having one object and multiple objects with the same value.您不能合法地更改
const
object 的值,因此拥有一个 object 和具有相同值的多个对象之间没有明显的区别。
As you can put a definition of a const
object in a header file it makes trivial for the compiler to use the value directly at the compilation stage without such optimizations having to be delayed to a link-time fixup.由于您可以将
const
object 的定义放在 header 文件中,因此编译器可以轻松地在编译阶段直接使用该值,而无需将此类优化延迟到链接时修复。
Basically, in C++, const, non-local variables are genuine constant expressions, or constexpr.基本上,在 C++ 中,const、非局部变量是真正的常量表达式或 constexpr。 This permits plenty of things, like TMP.
这允许很多东西,比如 TMP。
const int five = 5;
int main() {
int x[five];
std::array<int, five> arr;
}
In C, they are just a variable that cannot be modified.在 C 中,它们只是一个不能修改的变量。 That is,
那是,
const int five = 5;
int main() {
int x[five]; // Technically, this is a variable length array
}
Is quite equivalent to相当相当于
int five = 5;
int main() {
int x[five];
}
Effectively, C++ promotes some kinds of const
variable to a new category, constexpr
, whereas in C, this does not exist and they are just variables which happen to be unmodifiable.实际上,C++ 将某些
const
变量提升到一个新类别constexpr
,而在 C 中,这不存在,它们只是碰巧不可修改的变量。
It looks like const doesn't actually generate an external symbol .看起来const 实际上并没有生成外部符号。
Why do English people spell COLOUR, whereas American people spells it COLOR?为什么英国人拼写颜色,而美国人拼写颜色?
They are 2 different languages from the same base, but they don't have the same rules.它们是来自同一基础的两种不同语言,但它们没有相同的规则。
C & C++ are the same. C & C++ 是一样的。 If they weren't different, they would both be called the same thing.
如果它们没有不同,它们将被称为同一个东西。
My workaround was declaring it as:我的解决方法是将其声明为:
static classfoo foo;
it worked in my situation.它适用于我的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.