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