请考虑以下代码段:
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;
...
}
所以我有两个标识符但是对于不同的对象(调用一个是正确的 功能一个对象?)。这是严格违法的,还是标准定义的 案例为“未定义的行为”。该标准的哪一部分描述了这一点?
答案 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();
}