долго долго в C / C ++ - PullRequest
       20

долго долго в C / C ++

82 голосов
/ 22 сентября 2009

Я пытаюсь этот код на компиляторе GNU C ++ и не могу понять его поведение:

#include <stdio.h>;

int main()
{
    int  num1 = 1000000000;
    long num2 = 1000000000;
    long long num3;
    //num3 = 100000000000;
    long long num4 = ~0;

    printf("%u %u %u", sizeof(num1), sizeof(num2), sizeof(num3));
    printf("%d %ld %lld %llu", num1, num2, num3, num4);
    return 0;
}

Когда я раскомментирую закомментированную строку, код не компилируется и выдает ошибку:

ошибка: целочисленная константа слишком велика для типа long

Но если код скомпилирован как есть и выполняется, он выдает значения, намного превышающие 10000000000.

Почему?

Ответы [ 4 ]

143 голосов
/ 22 сентября 2009

Буквы 100000000000 составляют буквенную целочисленную константу, но значение слишком велико для типа int. Вам нужно использовать суффикс для изменения типа литерала, т.е.

long long num3 = 100000000000LL;

Суффикс LL превращает литерал в тип long long. C не настолько «умен», чтобы заключить это из типа слева, тип является свойством самого литерала, а не контекста, в котором он используется.

26 голосов
/ 22 сентября 2009

Попробуйте:

num3 = 100000000000LL;

И, кстати, в C ++ это расширение компилятора, стандарт не определяет long long, это часть C99.

4 голосов
/ 22 сентября 2009

Зависит от режима компиляции. long long не является частью стандарта C ++, но поддерживается только (как правило) как расширение. Это влияет на тип литералов. Десятичные целочисленные литералы без суффикса всегда имеют тип int , если int достаточно большой для представления числа, в противном случае - long. Если число слишком велико для длинных, результат определяется реализацией (возможно, это просто число типа long int, которое было усечено для обратной совместимости). В этом случае вы должны явно использовать суффикс LL, чтобы включить расширение long long (на большинстве компиляторов).

Следующая версия C ++ будет официально поддерживать long long таким образом, что вам не понадобится суффикс, если вы явно не хотите, чтобы тип литерала был как минимум long long. Если число не может быть представлено в long, компилятор автоматически попытается использовать long long даже без суффикса LL. Я считаю, что это поведение C99 также.

1 голос
/ 22 сентября 2009

ваш код компилируется здесь нормально (даже с этой строкой без комментариев. Пришлось изменить его на

num3 = 100000000000000000000;

чтобы начать получать предупреждение.

...