C++中的无符号算术运算

11

在进行无符号算术运算时,我发现了一个奇怪的现象。由于循环溢出,预计b-a具有相同的数字4294967286,但实际输出结果为-104294967286。请问有谁能给个提示?

#include <iostream>

int main() {
  unsigned int a = 10;
  int b = -a;
  std::cout << b << ", " << -a << std::endl;
}

https://repl.it/repls/ExpertDrabOrganization


2
你为什么期望一个 int 变量的值是 4294967286,这个值比 int 的最大值还要大呢? - molbdnilo
1
int b = -a; -> unsigned int b = -a; - Paul R
1
@molbdnilo 我的错。我忘记了 b 也会溢出。 - Zhe Chen
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
17

-a会使用unsigned算术运算进行求值,并且将是一个比std::numeric_limits<int>::max()更大的数字。 当一元运算符-应用于unsigned类型时,它的行为更像是一个模数运算符。

因此,由于对int进行了超出范围的赋值,您的程序的行为是实现定义的


3
implementation defined”意思是按照文档规定执行,如果实现者没有兑现承诺,就要向其抱怨。 - StoryTeller - Unslander Monica
@讲故事者:自哪个新潮的标准开始? - Bathsheba
1
@StoryTeller 在C++03中也是实现定义的。 - Angew is no longer proud of SO
2
@Angew - 有趣的是,在我手头的一个C99草案中,它的实现是定义的。似乎转换总是具有实现定义的语义。然而,在我检查过的任何地方,带符号类型的算术溢出都是UB。好奇。 - StoryTeller - Unslander Monica
1
gcc的实现定义行为:该值将被模2^N减少。clang也是如此。对于MSVC,这种行为不能保证:https://learn.microsoft.com/en-us/cpp/c-language/demotion-of-integers?view=vs-2017 - Oliv
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,