You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数声明符中的参数声明是否具有函数原型作用域?

C11标准中函数原型作用域的争议问题

咱们先从C11 ISO标准(草案)第6.2.1(2)条款的定义说起,我把重点标出来了:

函数原型是声明函数参数类型的函数声明。

按照这个定义,像下面这段代码:

void (*f)( struct s { int c; } );

本质上是指向函数的指针的声明,并非函数声明,所以这里的标记s应该根据声明出现的位置,拥有文件作用域或者块作用域。照这个逻辑,下面整个翻译单元应该完全符合标准(先暂不考虑实用性问题):

void (*f)( struct s { int c; } ); struct s a[42];

但实际用gcc编译时,却会弹出「数组类型不完整」的诊断信息,还附带一个关于s的作用域被限制在参数列表中的警告——这说明gcc认为s拥有的是函数原型作用域,可从形式上看这里根本没有函数声明啊。

我现在有几个核心疑问:

  • 标准的真实意图是不是说,每个函数声明符中的参数列表都有自己的作用域?这也是gcc及其他主流编译器的解读方式。
  • 这种意图在标准文本里有没有更正式、明确的表述?
  • 有没有相关的缺陷报告还没被纳入标准中?

当然我也清楚,这种「隐蔽的」标记声明属于不良编程风格。除了上面例子里a的声明中s是不完整类型的问题,作用域的问题还导致我们无法定义符合*f原型的函数。最后提个小细节,要是想避开使用f本身,可以把整个f的声明放进sizeof里,比如:

int b[sizeof(void (*)( struct s { int c; } ))];

内容的提问来源于stack exchange,提问作者alexsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:29