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的方面开始。
第一部分的第5节注释9讨论了如果操作数具有不同的位宽度,在继续操作之前,如果操作数相同但符号不同,该怎么办: 。。。 否则,如果具有无符号整数类型的操作数具有秩 大于或等于其他操作数类型的秩, 带符号整数类型的操作数应转换为 无符号整数类型的操作数 这就是我们了解到比较必须在无符号算术中操作的地方。我们现在需要了解这对值-10意味着什么 第4.6节告诉我们: 如果目标类型为无符号,则结果值最小 与源整数全等的无符号整数(模2 n,其中n 用于表示无符号类型的位数)。[注:在 二的补语表示法,这种转换是概念上的和逻辑上的 位模式没有变化(如果没有截断)- 结束说明]3如果目标类型已签名,则该值不变 如果可以在目标类型(和位字段宽度)中表示; 否则,该值由实现定义 如您所见,一个非常高的特定值(4294967286,或0xFFFFF6,假设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 用于表示无符号类型的位数)。[注:在 二的补语表示法,这种
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" );
}