Estou tentando este código no compilador C ++ do GNU e não consigo entender seu comportamento:
#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;
}
Ao remover o comentário da linha comentada, o código não compila e apresenta um erro:
erro: a constante inteira é muito grande para o tipo longo
Mas, se o código for compilado como está e for executado, ele produzirá valores muito maiores do que 10000000000.
Por quê?
c++
types
long-integer
sud03r
fonte
fonte
<stdint.h>
e useuint64_t
. Para exibir um valor de 64 bits,printf( "%" PRIu64 "\n", val);
<stdint.h>
incluídos,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 );
#define __STDC_FORMAT_MACROS 1
Consulte stackoverflow.com/questions/14535556/…Respostas:
As letras 100000000000 constituem uma constante inteira literal, mas o valor é muito grande para o tipo
int
. Você precisa usar um sufixo para alterar o tipo do literal, ou seja,long long num3 = 100000000000LL;
O sufixo
LL
transforma o literal em tipolong long
. C não é "inteligente" o suficiente para concluir isso a partir do tipo à esquerda, o tipo é uma propriedade do próprio literal, não do contexto no qual está sendo usado.fonte
int
,long int
elong long int
em que o seu valor pode ser representado. [C ++ §2.14.2 / 2] Portanto, agora não há necessidade de adicionar o sufixo 'LL' em um literal inteiro que é muito grande para outros tipos.Experimentar:
num3 = 100000000000LL;
E por falar nisso, em C ++ isso é uma extensão do compilador, o padrão não define long long, isso faz parte do C99.
fonte
Depende de qual modo você está compilando. long long não faz parte do padrão C ++, mas apenas (normalmente) é suportado como extensão. Isso afeta o tipo de literais. Literais inteiros decimais sem qualquer sufixo são sempre do tipo int se int for grande o suficiente para representar o número, caso contrário, longo. Se o número for muito grande por muito tempo, o resultado será definido pela implementação (provavelmente apenas um número do tipo long int que foi truncado para compatibilidade com versões anteriores). Nesse caso, você deve usar explicitamente o sufixo LL para habilitar a extensão longa longa (na maioria dos compiladores).
A próxima versão do C ++ oficialmente suportará long long de uma maneira que você não precisará de nenhum sufixo, a menos que você queira explicitamente que o tipo do literal seja pelo menos long long. Se o número não puder ser representado por muito tempo, o compilador tentará automaticamente usar long long mesmo sem o sufixo LL. Acredito que esse seja o comportamento do C99 também.
fonte
seu código compila aqui bem (mesmo com essa linha não comentada. teve que alterá-lo para
num3 = 100000000000000000000;
para começar a receber o aviso.
fonte
long
em linha com a ABI LP64 desse SO.