如果C代码比较不同的数据类型,如何获得警告?

如果C代码比较不同的数据类型,如何获得警告?,c,gcc,arm,C,Gcc,Arm,如果C代码中的开发人员正在比较不同的数据类型,我希望看到警告或错误。我使用的是gcc arm-none-eabi,我已经相应地尝试了以下代码和以下编译器标志 uint8_t foo = 0; int16_t bar = -1; int main() { while(1) { if (foo==bar) return 0; } } 编译器选项 -Wsign-compare -Wall -Wextra 但我看不到任何错误或警告,为什么?你能帮我吗 如果C代码比较不同的数据类型,

如果C代码中的开发人员正在比较不同的数据类型,我希望看到警告或错误。我使用的是gcc arm-none-eabi,我已经相应地尝试了以下代码和以下编译器标志

uint8_t foo = 0;
int16_t bar = -1;

int main() {
  while(1) {
    if (foo==bar) return 0;
  }
}
编译器选项

-Wsign-compare -Wall -Wextra
但我看不到任何错误或警告,为什么?你能帮我吗

如果C代码比较不同的数据类型,如何获得警告

=
使两个操作数按照其相对整数转换秩进行隐式转换。要获得警告,请进行比较,确定整数提升后,操作数的符号度不同

如果
int
可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为
int
;否则,它将转换为
无符号int
。这些被称为整数促销。C11dr§6.3.1.1 2

需要记住的一个关键概念是,整数升迁不会改变值,只会改变类型。在没有值变化的情况下,比较不会发生“意外”

转换可能会改变值。例如,
int-1
-->
unsigned UINT\u MAX


我看不到任何错误或警告,为什么

使用下面的
foo8==bar
,将
foo8
bar
升级为
int
没有任何重要的警告。对于
bar、foo8
的所有值组合,比较都有很好的定义-这并不奇怪。那是C

uint8_t foo8 = 0;
int16_t bar = -1;
uint32_t foo32 = 0;

int main(void) {
  if (foo8 == bar)  return 1;
  if (foo32 == bar) return 2;
}
使用
foo32==bar
foo32
变为
unsigned
(或
unsigned long
),并且
bar
被提升为
int
。使用各种编译器选项,您可以很容易地得到如下警告

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

在后一种情况下,要将[int_MIN…int_MAX]范围内的
int
与[0…UINT_MAX]范围内的
无符号
,并确保比较
-1,UINT_MAX
失败,代码可以使用:

// if (foo32 == bar) return 2;
if (bar >= 0 && foo32 == (unsigned)bar) return 2;

比较前,值提升为
int
;晋升时,他们的类型相同。这可能就是为什么你在比较中没有得到任何警告。在返回
int
的函数中没有值时,您应该会得到一个关于
返回的警告,除非编译器推断出该返回永远不会执行。“
-Wsign compare
-当有符号值转换为无符号值时,有符号值和无符号值之间的比较可能产生不正确的结果时发出警告。”
条形图
未转换为无符号类型。
-Wsign compare
仅适用于C++@KeineLust文档似乎暗示它在C上也可用:“-Wsign compare警告:当有符号值转换为无符号值时,有符号值和无符号值之间的比较可能产生不正确的结果。在C++中,这个警告也由-Wall启用。在C中,它也由-Wextra启用。“@JonathanLeffler你应该得到一个警告…不是在
main()
。Per:”。。。到达终止主函数的}返回值0…”