常量和全局
此代码将在 C++ 中产生错误
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
,因为许多人给出的原因是全局 const 具有内部作用域,并且它是默认静态的。
解决方案是:-
//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 的内存已经分配在其他文件中的某处。
对上面的代码应用相同的逻辑,任何人都可以解释这里发生的事情,或者 extern 在 c++ 中有不同的含义??
在此处输入链接说明
还要考虑这个页面它破坏了我所有的直觉..
This code will produce error in c++
// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
cout << Foo << endl;
return 0;
}
Reason as given by many is global const has internal scope and it is default static.
solution to this is :-
//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;
}
I used to think that extern is used to tell compiler that memory for the indentifer is already allocated somewhere in other files.
Applying same logic on above code can anyone explain what is happening here or extern has different meaning in c++??
enter link description here
Also consider this page it is spoiling my all intuitions..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果我们只需要声明一个全局常量(而不是
static
)怎么办?extern
如何帮助执行此操作?使用
extern
限定符声明的const
对象具有外部链接。因此,如果您想在多个翻译单元中使用
const
,请为其添加extern
限定符。全局变量默认具有外部链接,为什么 const 全局变量默认具有内部链接?
参考:
C++03 标准附录 C 兼容性 C.1.2 第 3 条:基本概念
通过遵循一个简单的规则来避免混淆:
默认情况下,对于非常量符号来说链接是外部的,对于常量符号来说链接是静态的(内部的)。
What if we have to declare only a global constant(not
static
)? Howextern
help in doing this?A
const
object declared withextern
qualifier has external linkage.So if you want to use a
const
across multiple Translation units, add anextern
qualifier to it.While a global variable has external linkage by default,why a const global has internal linkage by default?
Reference:
C++03 Standard Annex C Compatibility C.1.2 Clause 3: basic concepts
Avoid the confusion by following a simple rule:
By default Linkage is external for non-const symbols and static (internal) for const symbols.
快速提醒,以便清楚我们正在讨论的内容:
请注意,如果没有
const
,上面的前两个声明都是具有外部链接的定义。这绝不是正交的,并且
不是很直观,但这就是现行规则的规定。
给出 const 外部链接的问题是可能存在
具有外部链接的对象只有一个定义,并且具有一个
例外,只有定义可以有初始化程序。这意味着
对于具有外部链接的常量,实际值(如果
const 用于常量表达式)只能在一个中可见
翻译单位。这可能就是赋予
const
的动机默认内部链接。
当然,这至少会导致模板出现无穷无尽的问题
理论上;如果以下标头具有未定义的行为
包括多个翻译单元:
该标准规定,内联函数和模板不仅必须具有
相同的标记序列,但所有符号都必须绑定
每个翻译单元中的同一个对象,或者违反了
单一定义规则。并且由于
fixedValue
没有外部链接,每个翻译单元中有一个唯一的实例。 (有
异常如果符号引用
const
对象并且有立即左值到右值的转换。自从
std::vector::push_back
通过引用获取其参数,但是,没有立即左值到右值的转换,我们得到了 undefined
行为。)
当然,任何拥有模板的人:
也无法使用
fixedValue
实例化它。内部联系的原因当然是有历史原因的。今天,
编译器必须能够支持以下内容:
以及函数的各种重复定义。这将是
扩展允许初始化程序的规则相对简单
在类中对命名空间范围内的变量进行声明,以给出
类似于:
这将恢复正交性(即使需要额外的输入)。它
也会破坏几乎所有现有的代码。
另一种选择是处理
const
变量定义与今天处理函数模板完全相同:您可以有多个
定义,但它们必须全部相同。这可能会避免
大多数(如果不是全部)代码损坏。
A quick reminder, so that it is clear what we are talking about:
Note that without the
const
, the first two declarations above are bothdefinitions with external linkage. This is anything but orthogonal, and
not very intuitive, but this is what the current rules say.
The problem with giving a const external linkage is that there can be
only one definition of an object with external linkage, and with one
exception, only the definition can have an initializer. This means that
for a const with external linkage, the actual value (necessary if the
const is to be used in a constant expression) can only be visible in one
translation unit. This is probably the motivation for giving
const
internal linkage by default.
Of course, this causes no end of problems with templates, at least
theoretically; the following header has undefined behavior if it is
including in more than one translation unit:
The standard says that not only must inline functions and templates have
an identical sequence of tokens, but that all of the symbols must bind
to the same object in every translation unit, or there is a violation of
the one definition rule. And since
fixedValue
does not have externallinkage, there is a unique instance in each translation unit. (There is
an exception if the symbol refers to a
const
object and there isan immediate lvalue to rvalue conversion. Since
std::vector<int>::push_back
takes its argument by reference, however,there is no immediate lvalue to rvalue conversion, and we get undefined
behavior.)
And of course, anyone with a template:
cannot instantiate it with
fixedValue
either.The reason for the internal linkage is, of course, historical. Today,
compilers must be able to support things like:
and all sorts of duplicate definitions for functions. It would be
relatively trivial to extend the rules allowing initializers on a
declaration in a class to variables at namespace scope, to give
something like:
This would restore orthogonality (even if it required extra typing). it
would also break almost all existing code.
Another alternative would be to treat
const
variable definitionsexactly as function templates are treated today: you can have multiple
definitions, but they must all be identical. This would probably avoid
most, if not all, code breakage.