[英]Scope of parameters in a complex function definition
考虑以下模糊的函数定义,返回一个指向char
数组的指针:
char (*func(int var))[sizeof var]
{
return 0;
}
有效吗?
值得怀疑的部分是在sizeof
表达式中使用标识符var
。 至少根据GCC 4.9.2, var
在表达式sizeof
不可见。 (请注意,如果sizeof表达式中的var
替换为42
,则代码有效,此问题变得无趣。)
但是,在C11规范草案n1570中(相关部分在C99中相同,但可能有不同的子条款编号),第6.2.1节讨论了标识符的范围,并包含以下与此案例相关的句子:
6.2.1p4包含:
如果声明标识符的声明符或类型说明符出现在块内或函数定义中的参数声明列表中,则标识符具有块作用域,该作用域终止于关联块的末尾。
6.2.1p7包含(加粗矿井):
结构,联合和枚举标记具有在声明标记的类型说明符中标记出现之后开始的范围。 每个枚举常量都具有在枚举器列表中定义枚举器出现之后开始的范围。 任何其他标识符的范围都在其声明者完成之后开始。
显然, var
的声明var
出现在函数定义中的参数声明列表中。 因此,根据6.2.1p4,其范围在函数体的末尾结束(“关联块”)。 此外, var
明确对应于6.2.1p7中提到的“任何其他标识符”,因此其范围在其声明符完成之后,即在参数列表的末尾开始。
在我看来,规范没有说明var
的范围。 鉴于规范没有另外说明,对范围的“开始”和“结束”的明显(对我来说,无论如何)解释意味着范围从开始到结束跨越整个词汇间隔。 因此,似乎var
实际上应该在sizeof
表达式中可见。
规范中有什么我没有考虑到的吗? 标识符范围的概念是否应该以“从范围开始到范围结束的不间断词汇间隔”的其他方式进行解释? 如果是这样,在规范中这是如何表现的?
[sizeof var]
部分不是块的一部分,也不是声明列表的一部分,而是返回类型的一部分。 因此,可见的唯一标识符是具有文件范围的标识符。
函数的返回类型在声明函数本身的块作用域或文件作用域中定义。 它不属于函数定义的最外部块范围。 在此范围内(声明函数),尚未声明函数的参数。
您可以将功能定义视为
return type: char ( * )[sizeof var] // Oops..What is var?!
{
// function block scope including its parameters declarations;
int var;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.