3

这个问题应该是针对语言律师的。

假设 signed 和 unsigned int 都是 32 位宽。如 n3337.pdf 草案 5.3.1.8 所述,

(-(0x80000000u)) = 0x100000000u-0x80000000u = 0x80000000u

但我找不到问题的答案:签名的0x80000000 的一元减号是什么?是 UB、实现定义还是...?

问题主要是关于运行时计算。

   signed int my_minus(signed int i) { return -i;}
   ....
   int main() {
       signed int a = -0x7FFFFFFF; // a looks like 0x80000001
       signed int b = a - 1;       // b looks like 0x80000000
       std::cout << my_minus(b);
       ....
   }

不过,欢迎您对其他 2 个案例发表评论:

  • 编译时常量折叠,比如说,-(INT_MIN)

  • 编译时计算constexpr(如果与编译时常量折叠有区别)。


(请在为重复投票之前查看https://meta.stackexchange.com/questions/123713/is-splitting-a-question-a-good-practice 。)

4

2 回答 2

4

据我所知,有符号整数溢出始终是未定义的。来自 C++ 规范第5 节 Expressions,第 4 段:

如果在计算表达式期间,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。[注意:大多数现有的 C++ 实现忽略整数溢出。除以零的处理,使用零除数形成余数,所有浮点异常因机器而异,通常可以通过库函数进行调整。——尾注]

于 2012-02-28T03:52:56.253 回答
3

有符号整数类型遵循数学整数的规则,而无需添加计算机废话。-std::numeric_limits< signed_type >::min()如果给定类型不能代表结果数字,那么将是未定义的行为。

在 aconstexpr中,实现需要拒绝该表达式,因为任何导致未定义行为的东西都会使常量表达式无效,这是可诊断的规则。在这种情况下,该规则是 §5.19 中的禁止项目之一,

— 未在数学上定义或不在其类型的可表示值范围内的结果;

在常量折叠中,编译器最有可能插入溢出的值。

于 2012-02-28T03:50:53.583 回答