为什么将有符号值赋给无符号整数时编译器不会报错?- C++

20

我知道 unsigned int 不能存储负数值。但是下面的代码可以编译通过,没有任何错误/警告。

我知道无符号整型不能存储负数值,但下面的代码可以编译通过而不产生任何错误或警告。

unsigned int a = -10;

当我打印变量a时,输出的值是错误的。如果无符号变量不能保存有符号值,为什么编译器允许它们编译而不给出任何错误/警告呢?

有什么想法吗?

编辑

编译器: VC++编译器

解决方案

需要使用警告级别4。

5个回答

16

Microsoft Visual C++:

警告 C4245: 'initializing' : 从'int'转换为'unsigned int',有符号/无符号类型不匹配

在警告级别4。

G++

给出以下警告:

警告:将负值-0x00000000a'转换为无符号整数'

没有任何-W指令。

GCC

您必须使用:

gcc main.c -Wconversion

这将会给出以下警告:

警告:负整数隐式地转换为无符号类型

请注意,-Wall将不会启用此警告。


也许您只需要提高警告级别。


是的,那就是问题所在。我将警告级别提高了,现在我正在收到警告信息。 - Navaneeth K N
啊,你说得对。我已经用正确的信息编辑了我的帖子。我使用g++是因为他在使用C++,结果发现g++甚至不需要-Wall或-Wconversion。然而,如果只使用GCC,则确实需要像你建议的那样使用-Wconversion(而不是-Wall)。谢谢 :) - GManNickG
请注意,clang使用-Wconversion来引发此警告。 - gerowam

14
signed int 转换为 unsigned int 是C标准中已知的 "通常算术转换",因此不是错误。
编译器通常不会默认发出警告的原因是因为这在代码中非常普遍,一般会有太多的“假阳性”警告。 有很多代码处理本质上是无符号的事情,例如计算缓冲区大小。 在表达式中混合使用有符号和无符号值也很常见。
这并不意味着这些默默的转换不会导致错误。 因此,对于新代码启用警告可能不是一个坏主意,这样可以从一开始就使其“清洁”。 但是,我认为您可能会发现处理现有代码所发出的警告非常压力巨大。

2

我正在使用 g++ 4.9.2,并需要使用 -Wsign-conversion 选项来显示此警告。

gcc.gnu.org: 在 C++ 中,除非显式启用 -Wsign-conversion 选项,否则默认情况下不会发出关于有符号和无符号整数之间转换的警告。


1
我正在使用g++ 9.3.0,以上回答都没有触发警告。这应该是正确的答案。 - s.ouchene

2

-10被解析为整数值,将int赋值给unsigned int是允许的。要知道是否做错了什么,编译器必须检查您的整数(-10)是负数还是正数。由于这不仅仅是类型检查,我猜测它已经因性能问题而被禁用。


1

对于gcc编译器,您可以添加以下内容

gcc -Wconversion ...

这将会产生以下警告

warning: converting negative value '-0x0000000000000000a' to 'unsigned int'

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