Длинный длинный в C/С++

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

#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;
}

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

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

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

Почему?

Ответ 1

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

long long num3 = 100000000000LL;

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

Ответ 2

Try:

num3 = 100000000000LL;

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

Ответ 3

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

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

Ответ 4

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

num3 = 100000000000000000000;

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