GCC或Clang关于函数参数的名称在它自己的默认参数范围内的说法是正确的吗?

rkkpypqq  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(214)

我有一个小玩具程序:

static int value = 0;

int function(int &value=value) {
    return value;
}

int main() {
    function();
}

使用g++ 7.2进行编译:
测试结果显示,测试test.cc。
没问题的。
使用clang++-3.9编译:

  • -test.cc----------------------------------------------------------------
test.cc:3:25: error: default argument references parameter 'value'
int function(int &value=value) {
                        ^~~~~
test.cc:8:5: error: no matching function for call to 'function'
    function();
    ^~~~~~~~
test.cc:3:5: note: candidate function not viable: requires single argument 'value', but no arguments were provided
int function(int &value=value) {
    ^
2 errors generated.

砰谁说对了

iyzzxitl

iyzzxitl1#

我认为clang是正确的。从basic.scope.pdecl:
名称的声明点紧跟在其完整声明符(第dcl.decl(https://timsong-cpp.github.io/cppwp/n3337/dcl.decl)条)之后和其初始化器(如果有)之前,以下注解除外。[示例:

int x = 12;{ int x = x; }

这里,第二个x用它自己的(不确定的)值初始化。-示例结束]
此外,从dcl.fct.default中还可以看到:
每次调用函数时都会计算默认参数。未指定函数参数的计算顺序。因此,即使未计算函数的参数,也不应在默认参数中使用这些参数。在默认参数之前声明的函数参数在作用域中,并且可以隐藏命名空间和类成员名称

k2fxgqgv

k2fxgqgv2#

由于OP将问题标记为c++11,我检查了该版本的标准,并在[basic.lookup.unqual]子条款11中明确指出:
在查找用作函数参数声明子句中的默认参数(8.3.6)或用于构造函数的mem-initializer的表达式(12.6.2)的名称期间,函数参数名称是可见的,并隐藏在包含函数声明的块、类或命名空间范围中声明的实体的名称。
因此,金属撞击声是正确的。

rryofs0p

rryofs0p3#

这里Clang是正确的。首先,function's parameter scope定义为:
函数参数(包括出现在lambda声明符中的参数)或函数局部预定义变量([dcl.fct.def])具有函数参数作用域。函数参数或函数局部预定义变量的潜在作用域从其声明点开始。
并且声明点定义为
名称的声明点紧跟在其完整声明符之后和初始化器(如果有)之前,除非下面注明。[例如:

unsigned char x = 12;
{ unsigned char x = x; }

这里,第二个x用它自己的(不确定的)值初始化。-示例结束]
因此,value应该是您刚刚声明的value,而不是全局空间中的那个

相关问题