具有外部链接的编译器的不同行为

时间:2011-11-26 22:12:05

标签: c++ extern linkage

当我在VC ++ 10上编译以下源时,带有静态链接的i被分配给42 但是在G ++ 4.5.1上,source2.cpp中带有外部链接的i被分配给42

根据标准确定行为的标准是什么?为什么?

// source1.cpp

#include <iostream>

static int i = 0;

int h();
void foo()
{
     int i;
     {
         extern int i;
         i = 42;
     }
}

int main()
{
    foo();

    std::cout << i << std::endl;
    std::cout << h() << std::endl;
}

// source2.cpp

int i;
int h() { return i; }

1 个答案:

答案 0 :(得分:2)

ISO / IEC 14882:2011 3.5 / 6:

  

块作用域中声明的函数的名称和块作用域extern声明声明的变量的名称具有链接。如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接。如果存在多个这样的匹配实体,则该程序是不正确的。否则,如果未找到匹配的实体,则块范围实体将接收外部链接。

foo()的内部块内,声明int i;隐藏了全局命名空间范围内的声明:static int i;所以内部块中没有可见的i链接。这意味着extern int i;引用了名称空间中直接包含foo()的外部链接的实体。

分配应该影响具有外部链接的i(在source2.cpp中定义),它应该对i中定义的内部链接source1.cpp没有影响。< / p>