函数参数名在自身默认参数中作用域判定:GCC与Clang谁正确?
GCC vs Clang: 函数参数名在自身默认参数中的作用域判定谁符合C++标准?
直接给结论:Clang的行为完全符合C++标准,GCC这里是采用了非标准的扩展规则。
咱们先明确C标准的规定:对于函数参数的作用域,C11及后续版本的标准都清晰指出,参数名字的作用域是从该参数声明的结束位置才开始的。换句话说,当你写void f(int a = a)这类代码时,等号右侧的a其实还没进入作用域——左边参数a的声明还未完成,此时引用a属于使用未声明的标识符,编译器必须报错。
再看两个编译器的具体表现:
- GCC 7.2允许这种写法,是因为它做了自定义扩展:把参数名的作用域提前到了参数声明的起始位置,因此它认为右侧的
a已经是合法的参数名。这是GCC自身的非标准行为,并非C++标准要求。 - Clang++ 3.9严格遵循了标准规则,所以会报错提示
a未声明,这才是符合标准的正确处理方式。
举个更直观的对比例子:
- 不符合标准的写法(自身默认参数引用自己):
Clang会报错,GCC则通过编译(依赖扩展行为)。void bad_func(int a = a) {} - 符合标准的写法(引用已声明的其他参数):
两个编译器都会正常编译,因为void good_func(int b, int a = b) {}b的声明已经完成,作用域覆盖了a的默认参数。
总结来说:严格按照C++标准,函数参数名在自身的默认参数中是不在作用域内的,所以Clang的报错是正确的,GCC的编译通过属于扩展行为。
内容的提问来源于stack exchange,提问作者gct
相关产品推荐
相关产品推荐

