我应该禁用C编译器签名/未签名的不匹配警告吗?

时间:2009-02-05 13:03:53

标签: c compiler-construction warnings

当您尝试比较两个变量时,Microsoft C编译器会发出警告,其中一个是有符号的,另一个是无符号的。例如:

int a;    
unsigned b;

if ( a < b ) { // warning C4018: '&lt;' : signed/unsigned mismatch

}

在世界历史上,这个警告是否曾经发现过一个真正的错误?无论如何,为什么呢?

11 个答案:

答案 0 :(得分:30)

永远不要忽略编译器警告。

答案 1 :(得分:24)

哦,它有。但反过来说。 忽略这一天的警告给我带来了巨大的麻烦。我正在编写一个绘制图形的函数,并混合有符号和无符号变量。在一个地方,我将负数与无符号数进行比较:

int32_t t; ...
uint32_t ut; ...

if(t < ut) { 
    ...
}
猜猜发生了什么事?签名号码被提升为无符号类型,因此最后更大,即使它最初低于0。我花了几个小时才找到了这个bug。

答案 2 :(得分:4)

如果你不得不提出这个问题,你就不太了解是否可以安全地禁用它,所以答案是否定。

我不会禁用它 - 我不认为我总是比编译器更清楚(尤其是因为我经常不这样做),更特别是因为我有时会在编译器没有的情况下通过监督来犯错误。 / p>

答案 3 :(得分:3)

更改ab以使用已签名类型,或两者都使用无符号类型。但这可能不实际(例如,它可能超出你的控制范围)。

警告是为了捕捉带负值的有符号整数和无符号整数之间的比较 - 如果两个数字的大小都很小,前者将(错误地)被认为大于后者。

答案 4 :(得分:2)

二元运算符通常在进行比较之前将两种类型转换为相同的类型,因为一个是无符号的,它也将int转换为unsigned。通常这不会造成太大麻烦,但如果你的int是负数,这将导致比较错误。

e.g。从signed转换为unsigned时-1等于4294967295,现在将其与100(无符号)进行比较

答案 5 :(得分:2)

这些警告是出于某种目的......它们会让你仔细思考你的代码!

就个人而言,我总是会明确地投出签名 - &gt;无符号和无符号 - &gt;如果可能签署。通过这样做,您确保您获得交易的所有权,并且您知道将要发生什么。我意识到它可能并不总是可能的,取决于项目来执行此操作,但总是针对0编译器警告...它只能帮助!

答案 6 :(得分:0)

我编写的代码比我想承认的要长。从个人经验来看,忽略看似迂腐的编译器警告有时会产生非常不愉快的结果。

如果他们惹恼了你并且你接受/理解了这种情况,那就设置演员并继续前进。

最终,在设计新代码时,这些事情从被忽视的细微差别转变为有意识的决定。结果为mickmouse转角案件留下了更少的空间来破坏您或您的客户日以及整体质量更好的软件。

答案 7 :(得分:0)

我甚至配置了编译器使该警告成为编译错误。由于所有其他人已经提到的原因。

如果我遇到签名/未签名的不匹配,我会问自己为什么选择不同的“签名”。这通常是设计错误。

答案 8 :(得分:0)

@gimel关于拍摄链接后面的整条腿的解释对这个问题非常有用。

  

- “避免这些简单问题的人可能只会前往一个不那么简单的问题。”

当您在不同类型之间进行转换并且不检查那些可能会伤害您的值时,实际上总是如此。

/约翰

更新:从uint转换为int的正确方法是检查 对limits.h的值,或类似的东西。 (但我很少这样做,即使你知道我应该...... :-)

答案 9 :(得分:0)

我认为最好将您的未签名号码转换为签名号码(比较前)。 而不是相反。

答案 10 :(得分:-1)

C 允许您shoot yourself in the foot的众多方式中的一种 - 您最好知道自己在做什么。 C 引用归因于{{3>}, C ++ 的创建者。