【问题标题】:C99: Equality operator expression to bool conversion warningC99:相等运算符表达式到布尔转换警告
【发布时间】:2021-05-14 08:36:06
【问题描述】:

我正在使用 WindRiver Diab for Power PC(一种用于嵌入式系统的专有 C99 编译器)编译以下代码:

  #include <stdbool.h>
  
  bool foo(int a, int b)
  {
      return a == b; /* int to unsigned char conversion */
  }

我原以为这段代码编译时不会出现警告,但不是,编译器报告:

警告:...找到有符号到无符号的类型转换:int 到无符号字符

一方面,由于相等运算符表达式的类型是int,而bool(在这种情况下)的类型显然是unsigned char,因此警告似乎是有道理的。另一方面,代码看起来很标准。它不应该在没有警告的情况下编译吗?标准的说法是什么?

【问题讨论】:

  • 你能分享一下它是什么编译器吗? without warnings 警告是编译器的内部内容,它是特定编译器的实现质量。所以Shouldn't it compile without warnings? What is the standard saying?标准没有提到任何警告,也不关心警告。
  • 至于解决它,您可以尝试return x;,因为== true 是多余的。或者你可以试试return (bool) (x == true);。或者您可以禁用该警告。您还应该向供应商写一封投诉信。
  • 值得一提的是,包含&lt;stdbool.h&gt;,根据标准,应该导致bool扩展为_Bool而不是unsigned char,所以看起来编译器不符合C99 标准。
  • 请注意,即使 bool 表示为 unsigned char,从 int 到 bool 的转换与从 int 到 unsigned char 的转换相同。它被 C99 标准定义为将任何比较等于 0 的值转换为 false,将其他所有值转换为 true。
  • @AndrewHenle 为什么不两者兼而有之?

标签: c type-conversion language-lawyer c99


【解决方案1】:

警告是正确的,但很迂腐。 == 的结果肯定是 int (C 1999, §6.5.9 ¶3)。 _Boolbool 扩展为)是标准无符号整数类型之一(C 1999,§6.2.5 ¶6)。当然,bool 扩展为 _Bool(C 1999,§7.16 ¶2)。

但是,由于== 的结果是 0 或 1,编译器可以推断它不会因转换而受到任何不良影响,并且警告可能已被抑制。特别是,转换为 _Bool 被明确定义为 0 或 1(C 1999,§6.3.1.2 ¶1)。

问题中显示的警告未提及转换为bool_Bool,而是提及unsigned char。这似乎不合适,并且是编译器质量可以提高的另一个迹象。

为了比较,GCC 需要专门添加-Wconversion 才能获得这些转换警告。即使使用该标志,当将== 的结果转换为unsigned 时,GCC 也不会生成任何警告。而且,它不会对任何算术转换(包括负值)到_Bool 产生任何警告。


Keith Thompson 在评论中指出 _Boolunsigned char 在 C 中是不同的类型,不能被视为兼容类型。

【讨论】:

  • 如果警告说“找到有符号到无符号的类型转换:int 到 bool”或“int 到 _Bool”,我会称其为恰当但迂腐。但是没有转换为unsigned char,所以警告充其量是不正确的。 (该标准不要求警告是正确的,所以这并不一定意味着任何不符合。)
  • @KeithThompson 我同意这不是一个很有帮助的信息,而且还谈到了实施的质量。也许在内部编译器使用unsigned char 来表示_Bool
  • 也许吧。但是,如果它以使_Boolunsigned char 兼容的方式这样做,则它是不合格的。例如:_Bool *pb = 0; unsigned char *puc = pb; 需要诊断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多