fredericopissarra Posted April 10, 2019 at 05:58 PM Share Posted April 10, 2019 at 05:58 PM Para os puristas, testar por overflow de inteiros sinalizados, em C, é um "undefined behavior", como dito no artigo 6.5.6:8 da especificação ISO 9989:1999 (por exemplo). Mas, considerando que estive falando da plataforma Intel e em representações de complemento 2, os "macetes" que mostrei anteriormente funcionam muito bem. Mas, se, mesmo assim, o purista exigir uma solução "correta", o GCC oferece funções built in para testes de overflow: _Bool __builtin_add_overflow(a, b, [type] *res); _Bool __builtin_sub_overflow(a, b, [type] *res); _Bool __builtin_mul_overflow(a, b, [type] *res); Esses são MACROS e existem funções equivalentes para cada "tipo", basta mudar o nome da operação para sadd, ssub ou smul (int), saddl, ssubl ou smull (long) ou saddll, ssubll ou smulll (long long). Troque o s por u para operações 'unsigned'... Nos macros, "[type]" é apenas uma indicação que o ponteiro, que não pode ser NULL, deve apontar para os tipos de a e b... As funções retornam 1 se houver overflow e colocam o resultado no local apontado por res. Existem ainda as funções built in de mesmos nomes, mas terminadas em _p. Elas não armazenam o resultado, mas usam o tipo do terceiro argumento (portanto não são funções, mas macros) para determinar se houve ou não overflow... A documentação diz que as operações são feitas com "precisão infinita" e só depois reduzida para a precisão do tipo do terceiro argumento. Mas, ao que parece, o compilador não usa aritmética de múltipla precisão, no sentido de bibliotecas como libgmp ou libmp. Eis um exemplo de código: #include <stdio.h> int main( void ) { int o, r, a, b; // a + b, com certeza, vai dar overflow. a = (unsigned)-1 >> 1; b = 1; // Faz a adição e retorna o flag de overflow. o = __builtin_add_overflow(a, b, &r); printf( "%d + %d = %d (%sOVERFLOW)\n", a, b, r, o ? "" : "not " ); } Sem otimizações a chamada ao built in fica assim, em assembly: xor ecx,ecx add eax,edx seto cl ; EAX sai com a soma e ECX com o booleano. A vantagem de usar os built ins é que todo GCC suporta, para qualquer arquitetura... Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.