ão existe maneira útil e confiável de detectar excesso de número inteiro em C / C +

Não, isso não é uma duplicata deComo detectar excesso de número inteiro?. O problema é o mesmo, mas a questão é diferente.

O compilador gcc pode otimizar uma verificação de estouro (com -O2), por exemplo:

int a, b;
b = abs(a);                     // will overflow if a = 0x80000000
if (b < 0) printf("overflow");  // optimized away

As pessoas do GCC argumentam que isso não é um bug. O estouro é um comportamento indefinido, de acordo com o padrão C, que permite ao compilador fazerqualquer cois. Pelo visto,qualquer cois inclui assumir que o estouro nunca acontece. Infelizmente, isso permite que o compilador otimize a verificação de estouro.

A maneira segura de verificar o estouro é descrita em uma recenCERT paper. Este documento recomenda fazer algo assim antes de adicionar dois números inteiros:

if ( ((si1^si2) | (((si1^(~(si1^si2) & INT_MIN)) + si2)^si2)) >= 0) { 
  /* handle error condition */
} else {
  sum = si1 + si2;
}

Aparentemente, você deve fazer algo assim antes de todas as operações +, -, * e / e outras em uma série de cálculos, quando quiser ter certeza de que o resultado é válido. Por exemplo, se você deseja garantir que um índice de matriz não esteja fora dos limites. Isso é tão complicado que praticamente ninguém está fazendo isso. Pelo menos nunca vi um programa C / C ++ que faça isso sistematicamente.

Agora, este é um problema fundamental:

Verificar um índice de matriz antes de acessar a matriz é útil, mas não confiáve

Verificar todas as operações da série de cálculos com o método CERT é confiável, mas não é úti

Conclusão: Não há uma maneira útil e confiável de verificar se há estouro em C / C ++!

Recuso-me a acreditar que isso foi planejado quando o padrão foi escrit

Sei que existem certas opções de linha de comando que podem resolver o problema, mas isso não altera o fato de termos um problema fundamental com o padrão ou a interpretação atual del

Agora, minha pergunta é: as pessoas do GCC estão levando a interpretação de "comportamento indefinido" longe demais quando isso lhes permite otimizar uma verificação de estouro, ou o padrão C / C ++ está quebrad

Nota adicionada: Desculpe, você pode ter entendido mal a minha pergunta. Não estou perguntando como solucionar o problema - isso já foi respondidoem outro luga. Estou fazendo uma pergunta mais fundamental sobre o padrão C. Se não houver uma maneira útil e confiável de verificar se há excesso, o próprio idioma é duvidoso. Por exemplo, se eu criar uma classe de matriz segura com verificação de limites, devo estar em segurança, mas não o será se a verificação de limites puder ser otimizad

Se o padrão permitir que isso aconteça, então o padrão precisa de revisão ou a interpretação da revisão precis

Nota adicionada 2: As pessoas aqui parecem não querer discutir o conceito dúbio de "comportamento indefinido". O fato de o padrão C99 listar 191 tipos diferentes de comportamento indefinido ligaçã) é uma indicação de um padrão desleixad

uitos programadores aceitam prontamente a afirmação de que "comportamento indefinido" concede a licença para fazer qualquer coisa, incluindo a formatação do disco rígido. Eu acho que é um problema que o padrão coloque o excesso de números inteiros na mesma categoria perigosa que escrever fora dos limites da matri

Por que esses dois tipos de "comportamento indefinido" são diferentes? Porque

uitos programas dependem do excesso de número ser benigno, mas poucos programas dependem da gravação fora dos limites da matriz quando você não sabe o que exist

Escrever fora dos limites da matriz, na verdadepod faça algo tão ruim quanto formatar seu disco rígido (pelo menos em um sistema operacional desprotegido como o DOS), e a maioria dos programadores sabe que isso é perigos

Quando você coloca um excesso de número inteiro na categoria perigosa "vale tudo", ele permite que o compilador faça qualquer coisa, incluindo mentir sobre o que está fazendo (no caso em que uma verificação de excesso é otimizada)

Um erro como escrever fora dos limites da matriz pode ser encontrado com um depurador, mas o erro de otimizar uma verificação de estouro não pode, porque a otimização geralmente está desativada durante a depuraçã

O compilador gcc evita evidentemente a política "vale tudo" em caso de estouro de número inteiro. Em muitos casos, ele se abstém de otimizar, por exemplo. um loop, a menos que possa verificar se o estouro é impossível. Por alguma razão, o pessoal do gcc reconheceu que teríamos muitos erros se seguissem a política "vale tudo" aqui, mas eles têm uma atitude diferente em relação ao problema de otimizar uma verificação de estouro.

alvez esse não seja o lugar certo para discutir essas questões filosóficas. Pelo menos, a maioria das respostas aqui está errada. Existe um lugar melhor para discutir isso?

questionAnswers(4)

yourAnswerToTheQuestion