简体   繁体   English

为什么在 C++ 中允许对 const 全局变量进行多重定义,而在 C 中不允许?

[英]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 中,这不存在,它们只是碰巧不可修改的变量。

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.

相关问题 全局const变量定义-通过C ++中的extern访问 - global const variable definition - access through extern in c++ 为什么C ++中的多定义错误不是由const int声明引起的? - Why multiple definition error in C++ not caused by const int declaration? C ++允许重新定义全局(const)变量? - C++ allows redefinition of global (const) variable? 在C ++中声明全局范围变量const - Declare a global scope variable const in c++ C ++中一个变量定义列表中的Const和非const - Const and non-const in one variable definition list in C++ C ++:定义之前注册全局变量 - C++: Registration of Global Variable Before Definition 为什么在C ++中不允许初始化整数成员变量(不是const static)? - Why is initialization of integer member variable (which is not const static) not allowed in C++? c&c ++默认全局变量链接,多个声明和定义问题 - c & c++ default global variable linkage, multiple declaration & definition problem 为什么在 C 中不允许将数组的大小作为常量变量,但在 C++ 中却允许? - Why is the size of array as a constant variable not allowed in C but allowed in C++? 静态const声明,constexpr变量定义,有效的c ++? - Static const declaration, constexpr definition of variable, valid c++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM