Почему 0x8000000000000000LL считается неподписанным длинным длинным по gcc? - PullRequest
0 голосов
/ 26 октября 2018

Я компилирую фрагмент кода, где значение литерала 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 считается неподписанным?

1 Ответ

0 голосов
/ 26 октября 2018

Потому что так работает для целочисленных литералов, которые являются шестнадцатеричными или восьмеричными и не вписываются в целочисленный тип, предлагаемый суффиксом.

6.4.4.1p5 :

Тип целочисленной константы является первым из соответствующего списка, в котором может быть представлено ее значение.

enter image description here

Обратите внимание, что в отличие от десятичных целочисленных литералов шестнадцатеричные и восьмеричные литералы без суффикса u / U могут при поиске подходящего типа перевернуть знак типа перед подъемом к следующему более высокопоставленному целочисленному типу со знаком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...