constexpr评估负位移时的不确定行为?

Ber*_*ard 3 c++ bit-shift undefined-behavior constexpr

考虑以下代码片段:

int main(){
    constexpr int x = -1;
    if(x >= 0){
        constexpr int y = 1<<x;
    }
}
Run Code Online (Sandbox Code Playgroud)

GCC 7(可能还有其他版本的GCC)拒绝对此进行编译,并说:

error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

我可以猜想这可能是从哪里来的:constexpron 的声明y使GCC y在编译时进行评估,而在这里它可能是负数。删除constexpr修复错误。

但是,这是标准的未定义行为吗?条件始终为假,因此y将永远不会使用的值。

在我的实际代码中,x是模板参数,该参数可以为负,也可以不为负。

Sto*_*ica 5

GCC抱怨是因为您的定义y显然是格式错误的constexpr声明。首字母缩写词违反[expr.const] / 2,它指定:

表达式e是核心常量表达式, 除非按照抽象机的规则对e求值将对以下表达式之一求值:

  • 具有本国际标准[引言]至[cpp]条款中规定的未定义行为的操作[注:例如,包括带符号整数溢出(子句[expr]),某些指针算术([expr.add] ),除以零或某些移位运算

因此,您不能用于1<<x初始化y。分支将永远不会执行并且可以消除,这无关紧要。GCC仍然有义务验证其语义正确性。