【发布时间】:2018-03-12 17:47:53
【问题描述】:
参考this question。用于初始化constexpr 变量y 的核心常量表达式格式不正确。这么多是给定的。
但如果我尝试将if 变成if constexpr:
template <typename T>
void foo() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1 << x;
}
}
int main(){
foo<int>();
}
错误仍然存在。 GCC 7.2 仍然提供:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
但我认为语义检查应该留在丢弃的分支上。
通过constexpr lambda 进行间接处理确实有帮助,但是:
template <typename T>
void foo(){
constexpr int x = -1;
constexpr auto p = []() constexpr { return x; };
if constexpr (x >= 0){
constexpr int y = 1<<p();
}
}
y 上的 constexpr 说明符似乎改变了检查丢弃分支的方式。这是预期的行为吗?
@max66 非常友好地检查了其他实现。他报告说,GCC (7.2.0 / Head 8.0.0) 和 Clang (5.0.0 / Head 6.0.0) 都可以重现该错误。
【问题讨论】:
-
听起来像一个编译器错误。您是否尝试过其他实现?
-
@ShacharShemesh - 我自己没有。但是我链接的帖子的 OP 报告了 Clang and MSVC behave the same.
-
我确认了 clang++ 3.8.1 的问题
-
来自 wanbox 我看到问题仍然存在于 g++(7.2.0 和 Head 8.0.0)和 clang++(5.0.0 和 Head 6.0.0)。
-
我不认为“y 上的 constexpr 说明符似乎改变了丢弃分支的检查方式”,因为删除了
constexpr(简单地定义“int y = 1 y 是初始化运行时),但我看到一个警告(未使用的变量y);所以(如果我没记错的话)该分支已编译。或者更好,我认为正确的意思是constexpry被初始化编译时(所以1 << x被立即检查)并且没有被初始化运行时。
标签: c++ language-lawyer c++17 constexpr if-constexpr