我遇到了一些有趣的行为,gcc对常量符号的解释。我有一段代码(大大简化)如下所示:
strSQLPharmContact = "SELECT TOP 1 tbl_Contacts.ID,
tbl_Contacts.idSite, tbl_Contacts.role, tbl_Contacts.name,
tbl_Contacts.email, tbl_Contacts.phone, tbl_Contacts.involvement,
tbl_Contacts.Taken" _ & "FROM tbl_Contacts " _
& "WHERE (((tbl_Contacts.role)= 'Pharmacist') AND
((tbl_Contacts.involvement)=True) AND ((tbl_Contacts.Taken)=False)); "
当我编译上面的内容时,我得到了#define SPECIFIC_VALUE 0xFFFFFFFF
//...
int32_t value = SOMETHING;
if (value == SPECIFIC_VALUE) {
// Do something
}
一切都很好 - 似乎gcc将十六进制常量解释为无符号,并且不喜欢与有符号整数的比较。但是,如果我将定义更改为warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
之类的内容,警告就会消失。再一次,我并不特别惊讶 - 符号位为零会使gcc更乐意将常量解释为有符号值。令我惊讶的是,如果我将定义更改为#define SPECIFIC_VALUE 0x7FFFFFFF
,我仍然会收到警告。我希望明确告诉编译器将我的常量解释为有符号值会使警告静音。
答案 0 :(得分:3)
关于应用于整数的转化,请阅读C11 §6.3.1.1 。 §6.4.4.1 ¶5指定为整数常量指定的类型。 gcc应该坚持这些规则。
十六进制常量 实际上是无符号的(按标准)int
(假设32位整数)。这符合并且不是偶然的!
如果清除MSbit,则常量可以表示为(带符号)int
。所以比较顺利。仍然标准。
第三条消息缺少INT32_C
的定义,所以我无能为力。但我认为你现在可以解决这个问题。请记住,在#define中无法检测到错误,但只有在宏扩展后才能检测到错误。
一般规则是,如果你真的想要U
,可以将unsigned
添加到常量(是的,也适用于十六进制)。或者施展常数:
#define UVALUE ((uint32_t)0x7FFFFFFF)
这在这里会更好,因为它实际上并不依赖于int
的大小。