函数原型范围的例子

Example of function prototype scope

本文关键字:范围 原型 函数      更新时间:2023-10-16

有一个函数原型范围的定义(3.3.4/1 N3797):

在函数声明中,或在除函数定义的声明符(8.4),形参的名称(if(提供)具有函数原型作用域,该作用域在结束时终止最近的封闭函数声明符

我们能得到一个描述该规则的例子吗?

下面是一个简单的例子

int a;
void f( int a, int a );

编译器将对第二个参数a发出错误,因为它的名字与第一个参数的名字一致。也就是说,编译器将报告名称a的重新定义。相同的名称在同一作用域中定义两次。

或者另一个例子

struct A {};
void f( int A, struct A );

第一个参数名称隐藏了结构的名称,所以第二个参数使用结构的详细名称来定义。

这个例子涉及到一个相对少见但有时会遇到的错误

void foo(struct S *v);
struct S {
  int i;
};
int main() {
  struct S *p = 0;
  foo(p);           // ERROR: incompatible pointer types
}

上面的代码是病态的(借用一个c++术语),因为在声明foostruct S还不知道。因此,foo原型中的struct S被解释为新类型的前向声明。它具有函数原型作用域。一旦原型结束,它就超出了范围。这意味着foo原型中的struct S声明与随后的struct S声明完全无关。这是两种不同的类型。main内部的指针pfoo的参数类型不兼容。代码格式错误。

注意,如果你交换struct S的声明和foo的原型,在原型中的struct S的声明不再是前向声明。假定它引用前面声明的struct S。代码正确