gct*_*gct 38 c++ gcc clang language-lawyer c++11
我有一个小玩具程序:
static int value = 0;
int function(int &value=value) {
return value;
}
int main() {
function();
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ 7.2进行编译:
g ++ -std = c ++ 11 -Wall -Wextra test.cc -o test
没问题.
用clang ++编译 - 3.9:
clang ++ - 3.9 -std = c ++ 11 -Wall -Wextra test.cc -o test
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.
Run Code Online (Sandbox Code Playgroud)
KABOOM.谁是对的?
R S*_*ahu 32
我认为铿锵是正确的.来自basic.scope.pdecl:
名称的声明点紧跟在其完整的声明符(子句[dcl.decl])之后和其初始化程序之前(如果有的话),除非如下所述.[例如:
Run Code Online (Sandbox Code Playgroud)int x = 12;{ int x = x; }这里第二个x用它自己的(不确定的)值初始化. - 结束例子]
另外,来自dcl.fct.default:
每次调用函数时都会计算默认参数.函数参数的评估顺序未指定.因此,函数的参数不应在默认参数中使用,即使它们未被评估.在默认参数之前声明的函数的参数在范围内,并且可以隐藏命名空间和类成员名称
Joh*_*han 18
由于OP将问题标记为c ++ 11,我检查了该版本的标准,并在[basic.lookup.unqual]子条款11中明确指出:
在函数parameter-declaration-clause中查找用作默认参数(8.3.6)的名称或在构造函数(12.6.2)的mem-initializer表达式中使用时,函数参数名称是可见的,隐藏包含函数声明的块,类或命名空间范围中声明的实体的名称.
因此,铿锵是正确的.
Clang在这里是正确的.首先,函数的参数范围 定义为:
函数参数(包括出现在lambda声明符中的函数)或函数本地预定义变量([dcl.fct.def])具有函数参数作用域.参数或函数本地预定义变量的潜在范围从其声明点开始.[...]
而声明的定义是
声明的声明就在其完整的声明者之后和初始化者之前(如果有的话),除非如下所述.[例如:
Run Code Online (Sandbox Code Playgroud)unsigned char x = 12; { unsigned char x = x; }这里第二个x用它自己的(不确定的)值初始化. - 结束例子]
所以value应该是value你刚宣布的而不是来自全球空间的人