【问题标题】:Why are some non-constant expressions allowed as operands of a constexpr comma operator?为什么允许某些非常量表达式作为 constexpr 逗号运算符的操作数?
【发布时间】:2018-12-03 18:28:31
【问题描述】:

考虑一个简单的例子:

int foo() {
    return 3;
}

template <int>
struct Bar {};

int a;

int main() {
    int b;
    //Bar<((void)foo(), 1)> bar1;  //case 1. compilation error as expected
    Bar<((void)a, 2)> bar2;        //case 2. no error (long shot but `a' has a linkage so maybe expected)
    Bar<((void)b, 3)> bar3;        //case 3. no error ? (`b' does not have linkage) 
    (void)bar2;
    (void)bar3;
}

我会说这是一个错误,但最新的 [clang][gcc] 都接受代码,所以我可能缺少一些使代码有效的相关标准规则?

【问题讨论】:

  • 更简单的 MCVE 是 gcc.godbolt.org/z/1s3HFz
  • 不是答案,只是怀疑:使用(void)a, 2,编译器可以丢弃a;使用(void)foo(), 1,编译器(不包括“as-if”规则)执行非constexpr 函数并丢弃返回值。等高手,估计是foo()的执行问题。

标签: c++ c++11 language-lawyer constexpr comma-operator


【解决方案1】:

左值到右值的转换不会应用于逗号运算符的第一个参数,除非它是 volatile。因此,(void)a, 2(void)b, 3 是常量表达式。

见 [expr.comma]/1

...左边的表达式是一个弃值表达式...

和 [expr]/12

...当且仅当表达式是 volatile 限定的左值 类型,它是以下之一:...

【讨论】:

    猜你喜欢
    • 2019-04-25
    • 2013-05-10
    • 1970-01-01
    • 2010-09-10
    • 2014-12-03
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多