全局范围内的两个对象可以具有相同的名称吗?

时间:2011-06-17 16:34:37

标签: c global-variables

请考虑以下代码段:

struct foo_struct {
   int a;
   int b;
};

struct foo_struct *foo;
struct foo_struct foo_global;

int foo(int x)
{
  ....
  return 0;
}

int main(void)
{
   foo = &foo_global;
  ...
}

所以我有两个标识符但是对于不同的对象(调用一个是正确的 功能一个对象?)。这是严格违法的,还是标准定义的 案例为“未定义的行为”。该标准的哪一部分描述了这一点?

3 个答案:

答案 0 :(得分:3)

我明白了:

a.c:9: error: ‘foo’ redeclared as different kind of symbol
a.c:6: note: previous declaration of ‘foo’ was here

我非常怀疑这是合法的。您可以消除foo = &foo_global的歧义,因为您无法“覆盖”某个函数,但void *var = foo会不明确(foo是函数指针还是struct foo_struct指针?)。< / p>

现在标准:

  

6.2.1§2   对于标识符指定的每个不同实体,标识符仅在称为其范围的程序文本的区域内可见(即,可以使用)。由相同标识符指定的不同实体具有不同的范围,或者在不同的名称空间中。 [...]

因此标识符必须具有不同的范围或不同的名称空间。

  

6.2.1§4   如果是声明标识符的声明符或类型说明符   出现在任何块或参数列表之外,标识符具有文件范围,即   终止于翻译单元的末尾。 [...]

     

6.2.1§6   当且仅当它们的范围终止于同一时,两个标识符具有相同的范围   点。

这些表明两个标识符具有相同的范围(文件范围),它终止于翻译单元的末尾。

  

6.2.3§1   [...] [T]这里是各种标识符类别的单独名称空间,如下所示:

     
      
  • label names [...]

  •   
  • tags结构,联合和枚举[...]

  •   
  • 结构或工会的members [...]

  •   
  • 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量声明)。

  •   

名称空间相同,因为两者都是普通标识符。

因此,它们具有相同的范围和相同的名称空间,不符合6.2.1§2。

答案 1 :(得分:1)

你有没有尝试编译它? 使用gcc,这不合法,并且当然发生错误

error: ‘foo’ redeclared as different kind of symbol
error: previous declaration of ‘foo’ was here

答案 2 :(得分:0)

你可以有一个变量,哪个类型是一个指向funcion的指针,所以当你调用它时,你是调用函数还是变量指向的函数同名?这是模棱两可的。我认为这是非法的。例如在java中没有问题,因为你不能有一个指向函数的变量,因此如果你引用函数或变量,则使用括号消除歧义。

typedef void (*functiontype)();
functiontype func;

void f1 () {
    ...
}
void func () {
    ...
}
void main() {
    func = &f1;
    func();
}