为什么编译器不喜欢隐式地转换为uint?

Not*_*ure 3 c# c++ gcc visual-c++

我在C++和C#中遇到了关于uint使用的几个类似的怪癖,现在我想知道推理(对于每个例子可能完全不同).对于这两个示例,请注意我正在编译时将警告级别设置为最大值.

(1)gcc抱怨在下面将int与uint进行比较,而vc ++没有:

uint foo = <somevalue>;
if( foo == ~0 )  //right here
   ...
Run Code Online (Sandbox Code Playgroud)

比较0就好了,没有任何强制转换gcc和vc ++.

(2)在C#3.5中,我遇到了一个类似的问题.以下工作正常:

uint foo = 1;
uint bar = 2;
Run Code Online (Sandbox Code Playgroud)

但这会给出一个uint/int警告:

bool condition = <somevalue>;
uint foo = condition ? 1 : 2; //right here
Run Code Online (Sandbox Code Playgroud)

是什么给出了,为什么编译器对立即值的签名如此敏感?我完全理解从变量赋值时的问题,但这对我来说对于直接值是没有意义的; 在解析中是否存在一些隐藏的难以阻止此行为被允许?或者是什么?

编辑:是的,我知道我可以用'你'来填充我的数字,但是这可以回避我的问题,即隐含地向左侧投射,而不是明确地施放右侧.

Pop*_*lin 7

在没有明确的程序员意图的情况下混合有符号和无符号值可能会导致细微的错误.确实,int和uint都存储在相同大小(4字节)的内存位置中并且位置分配兼容,但它们在常见操作方面的位表示和行为是不同的,并且它们也具有不同的范围.

这就像解决数学问题并说为什么我不能以[0到4294967295]间隔自由地交换[-2147483648到2147483647]间隔?嗯,你可以,但如果你超出界限,结果可能不是正确的:).这就是为什么编译器要求你确认(通过明确),你没有错误地混合不同的类型.

同样在C#中,字面数字总是int32,如果你想要一些其他文字类型,如float,decimal,ulong等,你需要使用适当的后缀,在你的情况下:

uint foo = condition ? 1u : 2u; // uint literals;
Run Code Online (Sandbox Code Playgroud)

编辑:正如Andrew Hare指出的那样,C#整数文字不仅仅是int32,而是(int,uint,long,ulong),具体取决于大小,如下所述:

C#Inger文字 - MSDN