Por que a expressão (int) + 1e10 não produz -2147483648 como CSAPP descreve? [duplicado]

Dec 12 2020

Estou lendo CS: APP (um x86-64 assembly / livro de baixo nível) e menciona:

De floatou doublepara int, o valor será arredondado para zero. Por exemplo, 1.999será convertido para 1, enquanto −1.999será convertido para −1.Além disso, o valor pode estourar. Os padrões C não especificam um resultado fixo para este caso. Os microprocessadores compatíveis com Intel designam o padrão de bits [10 ... 00] ( TMinwpara o tamanho da palavra w) como um valor inteiro indefinido. Qualquer conversão de ponto flutuante em inteiro que não pode atribuir uma aproximação de inteiro razoável produz esse valor. Assim, a expressão (int) +1e10cede -2147483648, gerando um valor negativo a partir de um positivo.

O que são microprocessadores compatíveis com Intel mencionados aqui? x86arquitetura incluindo a série AMD?

De qualquer forma, tenho um Intel i5 com Win10 64 bits e tentei no Visual Studio:

    #include <iostream>
    using namespace std;
    
    int main() {
        int b = (int)+1e10;
        cout << b << endl;
    }

e obtém 1410065408como saída.

Também tentei int32_te consegui 1410065408também.

Então por que não tenho o resultado -2147483648que [10 ... 00]o livro descreve?

Respostas

2 chux-ReinstateMonica Dec 12 2020 at 09:49

Mesmo se o processador usado tiver "Qualquer conversão de ponto flutuante para inteiro que não pode atribuir uma aproximação de inteiro razoável produz esse valor.", O compilador não precisa seguir isso, pois pode usar outro código para atingir o objetivo.

Em particular, os valores que podem ser determinados no momento do compilador, como some_32_bit_int = (int)+1e10;podem obter um valor como some_32_bit_int = 10000000000 & 0xFFFFFFFF;ou 1410065408que é completamente independente de um processador.

Se o valor da parte integral não pode ser representado pelo tipo inteiro, o comportamento é indefinido. C17dr § 6.3.1.4 1

O livro descreve o processador, não o compilador.