当constexpr评估负面bitshift时,不确定的行为
Undefined behavior when constexpr-evaluating negative bitshift?
考虑以下代码片段:
int main(){
constexpr int x = -1;
if(x >= 0){
constexpr int y = 1<<x;
}
}
GCC 7(可能以及其他GCC的其他版本)拒绝编译并说:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
我可以猜测它可能来自何处:y
上的constexpr
声明使GCC在编译时评估y
,其中可能为负。删除constexpr
解决了错误。
但是,这是标准的不确定行为吗?条件始终是错误的,因此y
的值将永远不会使用。
在我的实际代码中, x
是一个模板参数,可能是否定的。
GCC抱怨,因为您对y
的定义是明确的constexpr
声明。初始齐尔违反[Expr.Const]/2,指定:
表达式e是 core constant表达式,除非 E评估E,遵循抽象机的规则,将 评估以下表达式之一:
- 通过该国际标准的[CPP]条款[intro]中指定的不确定行为的操作[注: 例如,包括签名的整数溢出(条款[Expr]), 某些指针算术([Expr.Add]),零,或 某些班次操作 - 结束注];
因此,您不能使用1<<x
初始化y
。该分支永远不会被执行并可以消除并不重要。海湾合作委员会仍然有义务验证其语义正确。
正如讲故事的人所解释的那样,这是预期的行为,因为负数的左数是未定义的行为,而导致Ub的表达不能用于核心常数表达式(事实,您在运行时不尝试访问该表达式的结果并没有改变您要求编译器在编译期间对其进行评估的事实)。
如果您的分支实际上取决于模板参数,则可以使用if constexpr
:
template<int x>
constexpr int foo() {
if constexpr (x >= 0) {
constexpr int y = 1 << x;
return y;
}
return 0;
}
编辑:正如讲故事的问题的答案所解释的那样,这仅在模板中起作用,并且只有条件取决于模板参数(答案中的更详细说明)。
相关文章:
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 不确定如何装饰我的C++库代码以在 C 中使用
- C++功能泄漏内存,我是C++新手,不确定如何解决
- "错误 C0000:语法错误,令牌"<EOF>"处出现意外$end,并且不确定
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- 为什么以下代码是不确定的?
- 编译错误:"lvalue required as left operand of assignment" 不确定原因
- 误用指针会产生分段错误。我仍然不确定如何纠正它
- 我不确定为什么代码没有运行,它在编译时抛出错误,说它无法找到 PrintArray()
- 不确定出了什么问题(字符串输入)
- C++睡眠时间不确定
- 在C++中做一个场景问题,我不确定如何处理布尔和if循环
- 代码输出随机符号,我不确定出了什么问题
- 可变值变化,不确定原因
- 有没有办法让C++从 cin 中接收不确定数量的字符串?
- 尝试一次将单个字符读取到大小不确定的数组中
- 我不确定如何引用此神经网络训练方法中的权重
- 函数参数:不确定排序还是未排序?
- std::random_device如何生成不确定的随机数?
- 当constexpr评估负面bitshift时,不确定的行为