c - 为什么 0x8000000000000000LL 被 gcc 认为是 unsigned long long?

标签 c gcc types literals

我正在编译一段代码,其中 0x8000000000000000LL 文字的值用于识别未知/不受支持的值。

LL 后缀表示该值应解释为 (signed) long long (int ),但是 gcc(我已经尝试过 4.8.5 和 4.1.1)说该值是 unsigned long long 类型。

我在这里放了一个示例代码:

#include <stdio.h>

#define UNKNOWN 0x8000000000000000LL

int main(void){
  long long value = 1000;

  if ((unsigned long long) value == UNKNOWN) {
    puts("Yes, they are different!!");
  }

  if (value == (long long) UNKNOWN) {
    puts("Yes, they are different!!");
  }

  if (value == UNKNOWN) {
    puts("Yes, they are different!!");
  }
  return 0;
}

用这个命令 gcc -Wsign-compare ll.c 编译的结果是这样的:

ll.c: In function ‘main’:
ll.c:16:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (value == UNKNOWN) {
             ^

为什么 0x8000000000000000LL 文字值被认为是无符号的?

最佳答案

因为它适用于十六进制或八进制的整数文字,并且不适合后缀建议的整数类型。

6.4.4.1p5 :

The type of an integer constant is the first of the corresponding list in which its value can be represented.

enter image description here

请注意,与十进制整数文字不同,没有 u/U 后缀的十六进制和八进制文字可以在搜索合适的类型时,在上升到之前翻转类型符号下一个更高级别的有符号整数类型。

关于c - 为什么 0x8000000000000000LL 被 gcc 认为是 unsigned long long?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53006486/

相关文章:

c++ - constexpr 和使用重新解释强制转换的静态 const void 指针的初始化,哪个编译器是正确的?

c - 编译c程序后如何获取.so文件?

types - 用于 Longs 的 Clojure 重载方法解析

sql - Varchar(255) 到 Varchar(MAX)

c - 将单词读入链接列表

c - 为什么我不能使用 C 打印此文件中的整个消息?

c++ - 错误的 "control reaches end of non-void function"gcc 警告怎么办?

java - Java 中的 Long.valueOf(0) 和 0L 有什么区别?

c++ - printf 对待 *p++ 的方式与对待 p 的方式不同

c - 用于解析 uevent 的 posix 正则表达式导致错误