C++ 常量与全局
这段代码将在c语言中产生错误++C++ 常量与全局,c++,global-variables,constants,extern,C++,Global Variables,Constants,Extern,这段代码将在c语言中产生错误++ // Foo.cpp const int Foo = 99; // Main.cpp extern const int Foo; int main() { cout << Foo << endl; return 0; } 许多人给出的理由是,全局常量有内部作用域,它是默认静态的 解决办法是:- //Foo.h extern const int Foo; // Foo.cpp
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
许多人给出的理由是,全局常量有内部作用域,它是默认静态的
解决办法是:-
//Foo.h
extern const int Foo;
// Foo.cpp
#include "Foo.h"
const int Foo = 99;
// Main.cpp
#include "Foo.h"
int main()
{
cout << Foo << endl;
}
我曾经认为extern是用来告诉编译器,indentifer的内存已经分配到了其他文件的某个地方。
在上面的代码中应用相同的逻辑,有人能解释这里发生的事情或者在C++中有不同的含义吗?
也考虑这个页面,它破坏了我所有的直觉。 如果我们必须声明一个全局常数而不是静态的呢?extern如何帮助做到这一点
使用外部限定符声明的常量对象具有外部链接。
因此,如果要跨多个翻译单元使用常量,请向其添加外部限定符
虽然默认情况下全局变量有外部链接,但为什么常量全局变量默认情况下有内部链接
参考:
C++03标准附录C兼容性C.1.2第3条:基本概念
更改:显式声明为const而非显式声明为extern的文件作用域的名称具有内部链接,而在C中则具有外部链接
理由:因为常量对象可以在C++中用作编译时值,所以此功能促使程序员为每个常量提供显式的初始值设定项值。此功能允许用户将常量对象放入包含在许多编译单元中的头文件中
通过遵循一条简单的规则来避免混淆:
默认情况下,非常量符号的链接是外部链接,常量符号的链接是静态内部链接。如果我们必须只声明全局常量而不是静态链接,该怎么办?extern如何帮助做到这一点
使用外部限定符声明的常量对象具有外部链接。
因此,如果要跨多个翻译单元使用常量,请向其添加外部限定符
虽然默认情况下全局变量有外部链接,但为什么常量全局变量默认情况下有内部链接
参考:
C++03标准附录C兼容性C.1.2第3条:基本概念
更改:显式声明为const而非显式声明为extern的文件作用域的名称具有内部链接,而在C中则具有外部链接
理由:因为常量对象可以在C++中用作编译时值,所以此功能促使程序员为每个常量提供显式的初始值设定项值。此功能允许用户将常量对象放入包含在许多编译单元中的头文件中
通过遵循一条简单的规则来避免混淆:
默认情况下,非常量符号的链接是外部链接,常量符号的链接是静态内部链接。快速提醒,以便清楚地了解我们所说的内容:
int const a; // illegal
int const a = 42; // definition, internal linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // definition , external linkage
注意,如果没有const,上面的前两个声明都是
具有外部链接的定义。这不是正交的,而且
不是很直观,但这是当前规则所说的
提供常量外部链接的问题在于可能存在
只有一个具有外部链接的对象定义,以及一个
例外,只有定义可以有初始值设定项。这意味着
对于具有外部链接的常量,如果
常量将在常量表达式中使用,但只能在一个表达式中可见
翻译股。这可能是给予const的动机
默认情况下为内部链接
当然,这至少会给模板带来无尽的问题
理论上;以下标头具有未定义的行为(如果
包括在多个翻译单元中:
#include <std::vector>
int const fixedValue = 42;
inline void insertFixedValue( std::vector<int>& dest )
{
dest.push_back( fixedValue );
}
也无法使用fixedValue对其进行实例化
当然,内部联系的原因是历史的。今天
编译器必须能够支持以下内容:
struct X
{
static int const a = 42; // declaration!!!, external linkage
};
函数的各种重复定义。是的
相对而言,扩展允许在
在类中声明命名空间范围内的变量,以
比如:
int const a; // illegal
int const a = 42; // definition, external linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // declaration, external linkage
这将恢复正交性,即使它需要额外的键入。信息技术
也会破坏几乎所有现有的代码
另一种选择是处理常量变量定义
正如今天处理函数模板一样:您可以有多个
定义,但它们必须完全相同。这可能会避免
大多数(如果不是全部的话)都是代码断裂。一个快速提醒,以便清楚地了解我们在谈论什么:
int const a; // illegal
int const a = 42; // definition, internal linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // definition , external linkage
注意,如果没有const,上面的前两个声明都是
具有外部链接的定义。这不是正交的,而且
不是很直观,但这是当前规则所说的
提供常量外部链接的问题在于可能存在
只有一个具有外部链接的对象定义,以及一个
例外,只有定义可以有初始值设定项。这意味着
对于具有外部链接的常量,如果
常量将在常量表达式中使用,但只能在一个表达式中可见
翻译单位
. 这可能是给予const的动机
默认情况下为内部链接
当然,这至少会给模板带来无尽的问题
理论上;以下标头具有未定义的行为(如果
包括在多个翻译单元中:
#include <std::vector>
int const fixedValue = 42;
inline void insertFixedValue( std::vector<int>& dest )
{
dest.push_back( fixedValue );
}
也无法使用fixedValue对其进行实例化
当然,内部联系的原因是历史的。今天
编译器必须能够支持以下内容:
struct X
{
static int const a = 42; // declaration!!!, external linkage
};
函数的各种重复定义。是的
相对而言,扩展允许在
在类中声明命名空间范围内的变量,以
比如:
int const a; // illegal
int const a = 42; // definition, external linkage
extern int const a; // declaration, external linkage
extern int const a = 42; // declaration, external linkage
这将恢复正交性,即使它需要额外的键入。信息技术
也会破坏几乎所有现有的代码
另一种选择是处理常量变量定义
正如今天处理函数模板一样:您可以有多个
定义,但它们必须完全相同。这可能会避免
大多数(如果不是全部的话)代码被破坏。extern const a;是无效的C++,我不认为。你需要像extern const int a这样的东西;您在第一个突出显示的块中有错误,但在最后一个块中是正确的。@RobertCrovella我认为它甚至都不是有效的C,今天,如果它是有效的,那肯定是不好的做法。我已经修好了;是无效的C++,我不认为。你需要像extern const int a这样的东西;您在第一个突出显示的块中有错误,但在最后一个块中是正确的。@RobertCrovella我认为它甚至都不是有效的C,今天,如果它是有效的,那肯定是不好的做法。我已经修好了。