C/C++ Scope在两个不同的.cpp文件中

Que*_*eer 5 c c++

我想知道为什么你不能在2个不同的.cpp文件中声明一个具有相同名称的全局.我的理解是考虑范围,它应该只对特定的.cpp文件可见,而不是其他地方,但它显然是在抱怨.我这样做的原因是代码中的通用性,就是这样.有任何想法吗?

编辑清晰度

a.cpp

int g_x;

b.cpp

int g_x;

Set*_*gie 7

要使全局变量(或函数)仅对其声明的文件可见,

  1. 宣布它static,或
  2. (在C++中首选的方式)将变量放在无名空间中.看起来这会使它从命名空间外部无法访问,但它实际上做的是使它对它所在的文件可见.

要访问一个全局变量(不是static或匿名命名空间)是在一些其他的文件,使用申报extern.

原因与两个不同文件中不能具有相同名称的功能的原因相同.它会混淆链接器,因为默认情况下全局变量具有外部链接.static或者在匿名命名空间中为它们提供内部链接,这使它们成为"本地全局变量".

  • @JohnDibling:我相信它在C++ 11中没有被弃用. (4认同)
  • 为此,不推荐使用`static`. (2认同)
  • @JohnDibling:通过Fred的链接,最终我们找到[相关的缺陷解决方案](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012).我以为Herb Sutter也在他的博客上提到了这一点,但我现在找不到它...... (2认同)

Alo*_*ave 5

问题:
全局变量具有外部链接,即:它们在整个程序中都可见.
如果2个不同的文件具有相同符号名称的变量,则它会破坏ODR(一个定义规则).

顾名思义,一个定义规则(ODR)要求具有外部链接,非内联函数,类,枚举或模板的对象在程序中只有一个定义.


解决方案:
文件中的全局变量应具有内部链接以避免违反ODR.有两种方法可以实现这一目标:

在文件中创建全局变量static
使用匿名/未命名的命名空间.


好读:
匿名/未命名的命名空间
Speaking Standardese:One Definition Rule


对于Standerdese粉丝:
C++ 11 3.2一个定义规则[basic.def.odr]:

任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义.

第3段:

每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义; 无需诊断.定义可以在程序中明确显示,可以在标准或用户定义的库中找到,或者(在适当的时候)隐式定义(见12.1,12.4和12.8).内联函数应在每个使用它的翻译单元中定义.

C++ 11 7.3.1.1未命名的命名空间[namespace.unnamed]

1/unnamed-namespace-definition的行为就好像被替换为

inlineoptnamespace unique { /* empty body */ }    
using namespace unique ;      
namespace unique { namespace-body }       
Run Code Online (Sandbox Code Playgroud)

当且仅当它出现在unnamed-namespace-definition中时,inline出现时,翻译单元中所有出现的unique都会被相同的标识符替换,并且此标识符与整个program中的所有其他标识符不同.

注意: C++ 03不赞成static在命名空间范围内声明对象,但在C++ 11中删除了此弃用.