constexpr评估负位移时的不确定行为? [英] Undefined behavior when constexpr-evaluating negative bitshift?

查看:193
本文介绍了constexpr评估负位移时的不确定行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码段:

int main(){
    constexpr int x = -1;
    if(x >= 0){
        constexpr int y = 1<<x;
    }
}

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

GCC 7 (and probably other versions of GCC) refuses to compile this and says:

error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]

我可以猜到这可能是从哪里来的:y上的constexpr声明使GCC在编译时评估y,在此它可能为负数.删除constexpr可修复该错误.

I can guess where this may have come from: the constexpr declaration on y makes GCC evaluate y at compile time, where it might be negative. Removing the constexpr fixes the error.

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

However, is this undefined behavior by the standard? The condition is always false, so the value of y will never be used.

在我的实际代码中,x是一个模板参数,它可以为负也可以不为负.

In my actual code, x is a template parameter, which may or may not be negative.

推荐答案

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

GCC complains because your definition of y is explicitly an ill-formed constexpr declaration. The initialzier violates [expr.const]/2, which specifies:

表达式e是核心常量表达式 除非 遵循抽象机的规则对e求值, 计算以下表达式之一:

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:

  • 具有本国际标准[注]至[cpp]条款中指定的不确定行为的操作. 包括,例如,有符号整数溢出(条款[expr]), 某些指针算术([expr.add]),除以零,或 某些换档操作-注释[];
  • an operation that would have undefined behavior as specified in Clauses [intro] through [cpp] of this International Standard [ Note: including, for example, signed integer overflow (Clause [expr]), certain pointer arithmetic ([expr.add]), division by zero, or certain shift operations  — end note ] ;

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

So you can't use 1<<x to initialize y. It doesn't matter that the branch will never be executed and can be eliminated. GCC is still obligated to verify it's semantically correct.

这篇关于constexpr评估负位移时的不确定行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆