C++函数默认参数能否引用自身名称,Clang与GCC谁符合标准
结论
以正式发布的C标准(C20及更早版本)为判定基准,GCC的实现符合标准规范,Clang的兼容行为是对尚未正式纳入标准的缺陷修改的提前实现。
原理说明
1. 普通变量初始化的合法性
你提到的变量初始化写法int x = sizeof(x);是标准明确允许的:
按照C++的声明点规则,变量x的声明点位于完整声明符int x之后、初始化表达式= sizeof(x)之前,因此sizeof操作符引用的x已经完成声明。同时sizeof是不求值操作符,不需要变量完成初始化就可以合法调用,因此该写法完全合规。
2. 函数默认参数的规则差异
对于void f(int y = sizeof(y)) {}这类写法,两者行为差异的根源在于对默认参数作用域规则的实现不同:
- 现行正式发布的C标准(C20及更早)明确规定:函数参数的名称不得出现在默认参数的表达式中。这是因为默认参数的求值发生在函数调用点,而非函数声明点,此时参数尚未完成实例化,因此常规场景下引用参数名称属于非法行为,GCC的报错正是遵循了这一规则。
- 针对
sizeof、decltype这类不求值操作的特殊场景,C++标准委员会已经通过了编号为CWG 2082的缺陷修改决议,明确允许在不求值操作的操作数中引用参数自身名称。Clang已经提前实现了该决议内容,因此可以编译通过示例代码。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

