Próbuję tego kodu na kompilatorze GNU C ++ i nie jestem w stanie zrozumieć jego zachowania:
#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;
}
Kiedy odkomentuję skomentowaną linię, kod nie kompiluje się i wyświetla błąd:
błąd: stała całkowita jest za duża dla typu długiego
Ale jeśli kod zostanie skompilowany tak, jak jest i jest wykonywany, generuje wartości znacznie większe niż 10000000000.
Czemu?
c++
types
long-integer
sud03r
źródło
źródło
<stdint.h>
i użycieuint64_t
. Aby wyświetlić wartość 64-bitową,printf( "%" PRIu64 "\n", val);
<stdint.h>
,uint64_t a = 0xffffffffffffff; printf( "%" PRIu64 "\n",a ); : error: expected ‘)’ before ‘PRIu64’ printf( "%" PRIu64 "\n",a ); :: warning: spurious trailing ‘%’ in format [-Wformat=] printf( "%" PRIu64 "\n",a );
Odpowiedzi:
Litery 100000000000 tworzą literalną stałą całkowitą, ale wartość jest zbyt duża dla typu
int
. Musisz użyć sufiksu, aby zmienić typ literału, tjlong long num3 = 100000000000LL;
Przyrostek
LL
przekształca literał w typlong long
. C nie jest wystarczająco „inteligentny”, aby wywnioskować to na podstawie typu po lewej stronie, typ jest własnością samego literału, a nie kontekstu, w którym jest używany.źródło
int
,long int
ilong long int
w którym jego wartość może być reprezentowany. [C ++ §2.14.2 / 2] Dlatego teraz nie ma potrzeby dodawania sufiksu „LL” do literału liczby całkowitej, który jest zbyt duży dla innych typów.Próbować:
num3 = 100000000000LL;
A tak przy okazji, w C ++ jest to rozszerzenie kompilatora, standard nie definiuje long long, to część C99.
źródło
To zależy w jakim trybie kompilujesz. long long nie jest częścią standardu C ++, ale jest obsługiwany tylko (zwykle) jako rozszerzenie. Wpływa to na rodzaj literałów. Dziesiętne literały liczb całkowitych bez sufiksu są zawsze typu int, jeśli liczba int jest wystarczająco duża aby reprezentować liczbę, w przeciwnym razie long. Jeśli liczba jest zbyt duża przez długi czas, wynik jest zdefiniowany przez implementację (prawdopodobnie tylko liczba typu long int, która została obcięta w celu zapewnienia zgodności z poprzednimi wersjami). W takim przypadku musisz jawnie użyć sufiksu LL, aby włączyć długie, długie rozszerzenie (w większości kompilatorów).
Następna wersja C ++ będzie oficjalnie obsługiwać long long w taki sposób, że nie będziesz potrzebować żadnego sufiksu, chyba że jawnie chcesz, aby typ literału był co najmniej długi. Jeśli liczba nie może być reprezentowana w postaci długiej, kompilator automatycznie spróbuje użyć long long, nawet bez sufiksu LL. Uważam, że jest to również zachowanie C99.
źródło
twój kod kompiluje się tutaj dobrze (nawet jeśli ta linia nie jest komentowana. Musiałem zmienić to na
num3 = 100000000000000000000;
aby zacząć otrzymywać ostrzeżenie.
źródło
long
zgodnie z ABI LP64 tego systemu operacyjnego.