constexpr 具有未触及的非 constexpr 参数:谁是正确的,clang 还是 gcc?

Posted

技术标签:

【中文标题】constexpr 具有未触及的非 constexpr 参数:谁是正确的,clang 还是 gcc?【英文标题】:constexpr with untouched non-constexpr arguments: Who is correct, clang or gcc? 【发布时间】:2017-03-24 11:03:49 【问题描述】:

我有 4 个测试用例,我相信它们都是有效的:

constexpr int f(int const& /*unused*/)
    return 1;


void g(int const& p)
    constexpr int a = f(p); // clang error, gcc valid

    int v = 0;
    constexpr int b = f(v); // clang valid, gcc valid

    int const& r = v;
    constexpr int c = f(r); // clang error, gcc error

    int n = p;
    constexpr int d = f(n); // clang valid, gcc valid


int main()
    int p = 0;
    g(p);

Clang 和 GCC 仅在第一个测试用例上有所不同。

我使用 clang 4 & 5 (20170319) 和 GCC 7.0.1 (20170221) 进行了测试。

如果我是对的,它将大大简化 static_assert 中 boost::hana 的使用。

【问题讨论】:

【参考方案1】:

[expr.const]/2:

表达式e 是一个核心常量表达式,除非 评估e,遵循抽象机器的规则,将 计算以下表达式之一:

[...]

一个 id-expression 引用引用类型的变量或数据成员,除非该引用具有前面的初始化和 要么

用常量表达式初始化或

它的生命周期从e 的评估开始;

[...]

pr 都不满足任何条件。因此f(p)f(r) 都不是核心常量表达式,因此两者都不能用于初始化constexpr 变量。 Clang 是正确的。

【讨论】:

以上是关于constexpr 具有未触及的非 constexpr 参数:谁是正确的,clang 还是 gcc?的主要内容,如果未能解决你的问题,请参考以下文章

为啥右值不能分配给 constexpr 引用变量

未捕获 constexpr 变量

c++ 默认构造函数 constexpr 还是正确未定义?

未定义的对静态constexpr char []的引用

对静态 constexpr 数据成员的未定义引用错误

if constexpr 在模板化 lambda 中未丢弃的错误分支