GCC 或 Clang 关于函数参数在其自己的默认参数中的范围内的名称是否正确?
Is GCC or Clang correct about the name of a function parameter being in scope in its own default argument?
我有一个小玩具程序:
static int value = 0;
int function(int &value=value) {
return value;
}
int main() {
function();
}
使用 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.
卡布姆。 谁是对的?
我认为clang是正确的。从basic.scope.pdecl:
名称的声明点紧接在其完整声明符(子句 [dcl.decl])之后和初始值设定项(如果有)之前,除非下面另有说明。[ 示例:
int x = 12;{ int x = x; }
在这里,第二个 x 使用它自己的(不确定)值进行初始化。 — 结束示例 ]
另外,从dcl.fct.default:
每次调用函数时都会计算默认参数。未指定函数参数的计算顺序。因此,函数的参数不应在默认参数中使用,即使它们未被计算。在默认参数之前声明的函数的参数在作用域中,可以隐藏命名空间和类成员名称
由于 OP 将问题标记为 c++11,我检查了该版本的标准,并在 [basic.lookup.unqual] 子条款 11 中明确指出:
在查找用作默认参数 (8.3.6) 的名称期间 函数参数声明子句或用于表达式 构造函数 (12.6.2) 的 mem 初始值设定项,函数参数 名称可见,并隐藏在 包含函数声明的块、类或命名空间作用域。
因此,叮当是正确的。
Clang在这里是正确的。 首先,函数的参数范围定义为:
函数参数(包括出现在 lambda 声明符中的参数)或函数局部预定义变量 ([dcl.fct.def]) 具有函数参数范围。参数或函数局部预定义变量的潜在范围从其声明点开始。[...]
声明点定义为
名称的声明点紧接在其完整声明符之后和初始值设定项(如果有)之前,除非下面另有说明。[ 示例:
unsigned char x = 12; { unsigned char x = x; }
在这里,第二个x用它自己的(不确定的)值初始化。
所以value
应该是你刚刚宣布的value
,而不是来自全球空间的
- 为什么在全局范围内使用"extern int a"似乎不行?
- 错误:未在此范围内声明'reverse'
- 并行用于C++17中数组索引范围内的循环
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 不计算一个范围内的完美数
- 错误:"imread"未在此范围内声明
- 我在范围内未声明的错误类有问题
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 我有一个数组,我想输入一个范围,然后找到范围内所有偶数的总和?
- 未在此范围内声明错误 'xy'
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 命名空间范围内的外部 - GCC vs clang vs msvc
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 参数包内 noexcept 说明符
- basic_string::替换的超出范围异常,而在范围内,正如调试相同参数的输出所证明的那样
- GCC 或 Clang 关于函数参数在其自己的默认参数中的范围内的名称是否正确?
- 头文件中的函数参数"未在此范围内声明"
- 3 错误:错误:未在此范围内声明'Entry'。错误:模板参数 1 无效。错误:令牌之前声明中的类型无效'('
- 模板 模板参数不在范围内
- 'make_error_code' 未在此范围内声明,并且在实例化点通过依赖于参数的查找未找到任何声明