Ash*_*ppa 28 c c++ const one-definition-rule
由于One Definition Rule,C或C++中不允许对全局变量进行多重定义.但是,在C++中,const全局变量可以在多个编译单元中定义而没有错误.这和C中的不一样.
为什么C++允许这样做而C不允许?与C相比,为什么const全局的使用和行为在C++中以这种方式与非const全局不同?关于const,C++和C的内容正在发生什么?
例如,这在C++中是允许的,但在C中是错误的:
// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
int main()
{
cout << Foo << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这对C来说很好,但C++有问题:
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Naw*_*waz 28
// Foo.cpp
const int Foo = 99;
// Main.cpp
const int Foo = 99;
Run Code Online (Sandbox Code Playgroud)
const命名空间范围的变量具有内部链接.所以它们基本上是两个不同的变量.没有重新定义.
来自@ David的评论,3.5/3 [basic.link]:
具有命名空间作用域(3.3.5)的名称具有内部链接(如果它是
- 一个显式声明为静态的对象,引用,函数或函数模板的名称),
或者是显式声明为const且未显式声明的对象或引用的名称外部或以前宣布有外部联系 ; 或
- 匿名联盟的数据成员.
在第二种情况下,你应该这样做(正确的方式):
//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;
}
Run Code Online (Sandbox Code Playgroud)
我认为你要求的理由而不是具体的语言规则.
这样做的理由是它使const变量更容易使用.它为一种常见用途提供了类型替换#define.
而不是#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<int, five> arr;
}
Run Code Online (Sandbox Code Playgroud)
在C中,它们只是一个无法修改的变量.那是,
const int five = 5;
int main() {
int x[five]; // Technically, this is a variable length array
}
Run Code Online (Sandbox Code Playgroud)
相当于
int five = 5;
int main() {
int x[five];
}
Run Code Online (Sandbox Code Playgroud)
实际上,C++将某些类型的const变量提升到一个新类别,constexpr而在C语言中,它不存在,它们只是碰巧不可修改的变量.
| 归档时间: |
|
| 查看次数: |
8618 次 |
| 最近记录: |