visualc&x2B+;2010年:为什么;“有符号/无符号不匹配”;如果我添加“则会消失”;常数;给一个比较者? 我有以下简单的C++代码: #include "stdafx.h" int main() { int a = -10; unsigned int b = 10; // Trivial error is placed here on purpose to trigger a warning. if( a < b ) { printf( "Error in line above: this will not be printed\n" ); } return 0; } #包括“stdafx.h” int main() { int a=-10; 无符号整数b=10; //此处故意放置了一个小错误以触发警告。 if(a它是VisualStudio Bug,但是让我们从不是bug的方面开始。

visualc&x2B+;2010年:为什么;“有符号/无符号不匹配”;如果我添加“则会消失”;常数;给一个比较者? 我有以下简单的C++代码: #include "stdafx.h" int main() { int a = -10; unsigned int b = 10; // Trivial error is placed here on purpose to trigger a warning. if( a < b ) { printf( "Error in line above: this will not be printed\n" ); } return 0; } #包括“stdafx.h” int main() { int a=-10; 无符号整数b=10; //此处故意放置了一个小错误以触发警告。 if(a它是VisualStudio Bug,但是让我们从不是bug的方面开始。,c++,visual-studio-2010,C++,Visual Studio 2010,第一部分的第5节注释9讨论了如果操作数具有不同的位宽度,在继续操作之前,如果操作数相同但符号不同,该怎么办: 。。。 否则,如果具有无符号整数类型的操作数具有秩 大于或等于其他操作数类型的秩, 带符号整数类型的操作数应转换为 无符号整数类型的操作数 这就是我们了解到比较必须在无符号算术中操作的地方。我们现在需要了解这对值-10意味着什么 第4.6节告诉我们: 如果目标类型为无符号,则结果值最小 与源整数全等的无符号整数(模2 n,其中n 用于表示无符号类型的位数)。[注:在 二的补语表示法,这种

第一部分的第5节注释9讨论了如果操作数具有不同的位宽度,在继续操作之前,如果操作数相同但符号不同,该怎么办:

。。。 否则,如果具有无符号整数类型的操作数具有秩 大于或等于其他操作数类型的秩, 带符号整数类型的操作数应转换为 无符号整数类型的操作数

这就是我们了解到比较必须在无符号算术中操作的地方。我们现在需要了解这对值-10意味着什么

第4.6节告诉我们:

如果目标类型为无符号,则结果值最小 与源整数全等的无符号整数(模2 n,其中n 用于表示无符号类型的位数)。[注:在 二的补语表示法,这种转换是概念上的和逻辑上的 位模式没有变化(如果没有截断)- 结束说明]3如果目标类型已签名,则该值不变 如果可以在目标类型(和位字段宽度)中表示; 否则,该值由实现定义

如您所见,一个非常高的特定值(4294967286,或0xFFFFF6,假设
unsigned int
是一个32位数字)与10进行比较,因此标准保证
printf
实际上从未被调用

现在您可以相信我,在这种情况下,标准中没有要求诊断的规则,因此编译器可以自由地不发布任何诊断。(事实上,有些人编写
-1
是为了生成一个全一位模式。另一些人使用
int
迭代数组,这会导致
size\u t
int
之间的有符号/无符号比较。虽然很难看,但保证可以编译。)

现在VisualStudio“自愿”发出一些警告

这将导致在默认设置(级别3)下出现警告:

但你的情况却有所不同:

int a = -10;
const unsigned int b = 10;
if( a < b ) // no warning
{
    printf( "Error in line above: this will not be printed\n" );
}
inta=-10;
常数无符号整数b=10;
if(a
没有任何警告。(好吧,如果你想确定的话,你应该用
-Wall
重试。)这是一个bug。微软关于它:

感谢您提交此反馈。这是一个我们需要解决的问题 应发出C4018警告。不幸的是,这一特殊问题没有得到解决 由于 我们现有的资源


出于好奇,我使用Visual Studio 2012 SP1进行了检查,但缺陷仍然存在-没有使用
-Wall发出警告

听起来像是编译器错误。它可能在优化变量,所以您只需要
a<10
@DBRalir:不,等等,就是这样!用编译时常量表达式初始化的整数类型的
常量
变量。。。它是
a@DBRalir由于“debug”未打印,因此条件计算不正确,因此在任何情况下都必须给出警告。@Yakk由于“debug”未打印,因此“它可以确保有符号/无符号不匹配不会导致问题,因此不需要警告”语句不可能是正确的-上面的代码中有一个明显的错误,添加“const”不会删除错误,但有关它的警告已删除。我不愿意将其称为错误;比较完全按照语言标准的要求进行评估。这很可能是一个逻辑错误(即,不是程序员想要的)。关于
-1
这件事,你可能是对的,我想我自己也做过。不过,使用
~0
更有意义。@markransem:
~0
的理论问题在于它的类型
int
,其行为和值取决于有符号表示。显然,在实践中,任何东西都使用2的补码,因此
~0==-1
。如果要可移植地最大化未签名类型(不重复类型名称或使用
decltype
),则需要分配
-1
~0U
。使用
-1
来强调无符号类型是算术模
2^n
,使用
~0U
来强调无符号类型是位域。哎呀,我应该在上面的评论中说使用
~0ULL
,因为如果目标类型大于
无符号int
,当然
~0U
会失败。如果您愿意依赖某一特定类型,则不需要使用
-
~
。就我个人而言,我使用
-1
,除了在比特旋转时。我已将警告级别从3(默认)更改为4(接近最大值)-我看不到任何C4245警告:(.您自己检查过吗?@EyeofHell-Oops-这取决于您将
常量
放在哪里。答案已更新,以涵盖这两种方式。
const int a = -10;
unsigned int b = 10;
if( a < b ) // C4245
{
    printf( "Error in line above: this will not be printed\n" );
}
int a = -10;
const unsigned int b = 10;
if( a < b ) // no warning
{
    printf( "Error in line above: this will not be printed\n" );
}