有函数原型作用域的定义(3.3.4/1 N3797):在函数声明中,或者在函数定义(8.4)的声明符之外的任何函数声明符中,参数的名称(如果提供)具有函数原型范围,该范围在最近的封闭函数声明符的末尾终止。我们能举一个例子来描述这个规则吗?
guicsvcw1#
这里有一个简单的例子
int a; void f( int a, int a );
编译器将对第二个参数a发出错误,因为它的名称与第一个参数的名称一致。也就是说,编译器将报告名称a的重定义。在同一作用域中定义了两次相同的名称。或者另一个例子
a
struct A {}; void f( int A, struct A );
第一个参数名称隐藏了结构名称,因此第二个参数使用结构的详细名称定义。
vcudknz32#
这里有一个例子,涉及一个相对罕见,但有时会遇到的错误
void foo(struct S *v); struct S { int i; }; int main() { struct S *p = 0; foo(p); // ERROR: incompatible pointer types }
上面的代码是病态的(借用C++术语),因为在声明foo时struct S还不知道。因此,foo原型中的struct S被解释为一个新类型的前向声明。它有 function prototype scope。一旦原型结束,它就超出了范围。这意味着foo原型中的struct S声明与其后的struct S声明完全无关。这是两种不同的类型。main中的指针p与foo的参数类型不兼容。代码格式不正确。请注意,如果交换struct S的声明和foo的原型,则w原型中的struct S声明不再是前向声明。假设引用先前声明的struct S。代码变得正确。
foo
struct S
main
p
2条答案
按热度按时间guicsvcw1#
这里有一个简单的例子
编译器将对第二个参数
a
发出错误,因为它的名称与第一个参数的名称一致。也就是说,编译器将报告名称a
的重定义。在同一作用域中定义了两次相同的名称。或者另一个例子
第一个参数名称隐藏了结构名称,因此第二个参数使用结构的详细名称定义。
vcudknz32#
这里有一个例子,涉及一个相对罕见,但有时会遇到的错误
上面的代码是病态的(借用C++术语),因为在声明
foo
时struct S
还不知道。因此,foo
原型中的struct S
被解释为一个新类型的前向声明。它有 function prototype scope。一旦原型结束,它就超出了范围。这意味着foo
原型中的struct S
声明与其后的struct S
声明完全无关。这是两种不同的类型。main
中的指针p
与foo
的参数类型不兼容。代码格式不正确。请注意,如果交换
struct S
的声明和foo
的原型,则w原型中的struct S
声明不再是前向声明。假设引用先前声明的struct S
。代码变得正确。