【发布时间】:2019-08-07 07:10:52
【问题描述】:
这段代码在所有四大编译器上都能正常编译,即使在-pedantic上也是如此
struct S
{
constexpr S(int a) {}
};
constexpr int f(S a)
{
return 1;
}
int main()
{
int a = 0;
S s(a);
constexpr int b = f(s);
}
但是,根据标准,这不应该是这样……对吧?首先,s 不能在常量表达式中使用[expr.const]/3,因为它不符合constexpr 或const 以及枚举或整数类型的标准。
其次,它不是 constant-initialized [expr.const]/2 因为初始化的完整表达式不会是 constant 表达式 [expr.const]/10 由于 lvalue-to在初始化构造函数的参数时,正在对一个在常量表达式中不可用的变量(a)执行-rvalue 转换。
所有这些编译器是否只是省略了构造函数参数的初始化,因为它没有副作用,并且它是否符合标准(我 99% 肯定它不是,这是它的唯一方法将是使sconstexpr,并将其传递给const int 或声明为constexpr 的int)?
【问题讨论】:
-
嗯,你的推理至少听起来是合理的......你可能忽略的一点是
f根本不使用参数a,所以无论如何结果仍然是 constexpr 。 如果我就在这里,那么如果您将传递给S的构造函数的参数存储在一个尚未添加的成员变量中并从f中返回该成员变量,那么编译应该会失败。跨度> -
也许我读错了,但为什么会有
a的左值到右值转换? 如果需要,函数的参数(包括构造函数)只会被隐式转换(包括值转换)。将不合格的非引用int传递给接受不合格的非引用int作为参数的函数根本不需要任何转换或转换,只需该值的普通副本。 -
@Aconcagua 正确,如果值被存储,则编译失败,但是需要初始化参数(标准不允许省略初始化)
-
不过,这种初始化没有任何副作用。这可能会产生一些影响。
-
expr3: s 未使用。 expr2:它是一个本地整数。编译器在编译时就知道该值。编译器很聪明。
标签: c++ language-lawyer