É numeric_limits <int> :: is_modulo logicamente contraditório?

Emoutra pergunta, o tópico destd::numeric_limits<int>::is_modulo veio. Mas quanto mais eu penso sobre isso, mais parece que algo está errado com a especificação ou com o GCC ou ambos.

Deixe-me começar com algum código:

#include <limits>
#include <iostream>

bool test(int x)
{
    return x+1 > x;
}

int main(int argc, char *argv[])
{
    int big = std::numeric_limits<int>::max();

    std::cout << std::numeric_limits<int>::is_modulo << " ";
    std::cout << big+1 << " ";
    std::cout << test(big) << "\n";
}

Quando eu compilo isso comg++ -O3 -std=c++11 (x86_64 GCC 4.7.2), produz a seguinte saída:

1 -2147483648 1

Isso é,is_modulo é verdade, mais umINT_MAX é negativo e um maisINT_MAX é melhor queINT_MAX.

Se você é o tipo de pessoa com alguma chance realista de responder a essa pergunta, já sabe o que aconteceu aqui. A especificação C ++ diz que o estouro de inteiro é Comportamento Indefinido; o compilador tem permissão para assumir que você não faz isso; portanto, o argumento parax+1 não pode serINT_MAX; portanto, o compilador pode (e irá) compilar otest função para retornartrue incondicionalmente. Por enquanto, tudo bem.

No entanto, oEspecificação C ++ 11 também diz (18.3.2.4 parágrafos 60-61):

static constexpr is_modulo;

Verdadeiro se o tipo for modulo.222 Um tipo é modulo se, para qualquer operação envolvendo+, -ou* em valores desse tipo cujo resultado ficaria fora do intervalo[min(),max()], o valor retornado difere do valor verdadeiro por um inteiro múltiplo demax() - min() + 1.

Na maioria das máquinas, isso éfalse para tipos flutuantes,true para inteiros não assinados etrue para inteiros assinados.

Observe que o parágrafo 5 da seção 5 ainda diz: "Se durante a avaliação de uma expressão, o resultado não for matematicamente definido ou não estiver na faixa de valores representáveis ​​para o seu tipo, o comportamento é indefinido." Não há menção deis_modulo == true criando uma exceção.

Então, parece-me que o padrão é logicamente contraditório, porque o estouro de inteiro não pode ser definido e indefinido simultaneamente. Ou, pelo menos, o GCC não está em conformidade, porque temis_modulo Comotrue mesmo que a aritmética assinada certamente não seja envolvida.

O buggy padrão é? O GCC não está em conformidade? Estou esquecendo de algo?

questionAnswers(1)

yourAnswerToTheQuestion