0

我在 gcc 对常量符号的解释中遇到了一些有趣的行为。我有一段代码(大大简化)如下所示:

#define SPECIFIC_VALUE 0xFFFFFFFF

//...

int32_t value = SOMETHING;
if (value == SPECIFIC_VALUE) {
    // Do something
}

当我编译上述内容时,我得到了warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

一切都很好 - 似乎 gcc 将十六进制常量解释为无符号,并且不喜欢与有符号整数进行比较。但是,如果我将定义更改为类似#define SPECIFIC_VALUE 0x7FFFFFFF的内容,警告就会消失。同样,我并不感到特别惊讶——符号位为零会使 gcc 更乐意将常量解释为有符号值。真正让我吃惊的是,如果我将定义更改为#define SPECIFIC_VALUE INT32_C(0xFFFFFFFF),我仍然会收到警告。我希望明确告诉编译器将我的常量解释为有符号值会使警告静音。

4

1 回答 1

3

阅读C11 § 6.3.1.1了解应用于整数的转换。§ 6.4.4.1 ¶5指定给定整数常量的类型。gcc 应该遵守这些规则。

十六进制常量实际上是无符号的(按照标准)int(假设为 32 位整数)。所以这符合而不是偶然!

但是,如果清除 MSbit,则常数可以表示为 (signed) int。所以比较顺利。还是标准的。

第三条消息缺少 的定义INT32_C,所以我对此无能为力。但我认为你现在可以自己解决这个问题。请记住,在“#define”中无法检测到错误,只有在宏展开后才能检测到该错误。

一般规则是U如果你真的想要添加到常量(是的,也适用于十六进制)unsigned。或者转换常量:

#define UVALUE ((uint32_t)0x7FFFFFFF)

在这里会更好,因为它不依赖于int实际的大小。

于 2015-06-04T00:42:05.527 回答