2014-09-04 18 views
5

mia domanda è semplice, se ho il seguente codice in C++:È un casting primitivo, crea un nuovo oggetto in memoria?

int main(int argc, const char * argv[]) 
{ 
    int i1 = 5; 
    int i2 = 2; 
    float f = i1/(float)i2; 
    std::cout << f << "\n"; 

    return 0; 
} 

è (float)i2 andando a creare un nuovo oggetto in memoria che si trova accanto andando a dividere i1 e assegnati sulla f o colata operatore è in qualche modo la traduzione di (float)i2 al volo e si fa la deviazione con la memoria extra per il casting?

Inoltre, che cosa sta succedendo nei casi in cui il casting richiede dimensioni diverse di variabili? (Per esempio da float a raddoppiare)

+0

Per eseguire il cast dalla doppia alla virgola mobile o viceversa, è possibile trovare alcune informazioni utili qui: http://stackoverflow.com/questions/16737615/how-is-actually-done-floating-point-conversion-double- to-float-or-float-to-doub – JBL

risposta

4

È (float)i2 andando a creare un nuovo oggetto in memoria

Il cast crea un oggetto temporaneo, che avrà la sua propria stoccaggio. Questo non è necessariamente nella memoria; è probabile che un piccolo valore aritmetico come questo venga creato e utilizzato in un registro.

Inoltre, che cosa sta succedendo nei casi in cui il casting richiede dimensioni di variabili diverse?

Poiché viene creato un nuovo oggetto, non importa se hanno una dimensione e una rappresentazione diverse.

1

Dipende dall'implementazione del compilatore e dall'architettura della macchina. Il compilatore può utilizzare i registri della CPU per le variabili temporanee e può anche utilizzare la memoria dello stack, se necessario. Studiare l'output a livello di assembly del compilatore ti dirà cosa fa in un caso particolare.

1

Il valore della conversione può essere memorizzato in memoria o in un registro. Dipende dal tuo hardware, dal compilatore e dalle opzioni di compilazione. Si consideri il risultato della compilazione del frammento con g++ -O0 -c -g cast_code.cpp su un Cygwin 64 bit gcc:

[...] 
    14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp) 
    int i2 = 2; 
    1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) 
    float f = i1/(float)i2; 
    22: f3 0f 2a 45 fc   cvtsi2ssl -0x4(%rbp),%xmm0 
    27: f3 0f 2a 4d f8   cvtsi2ssl -0x8(%rbp),%xmm1 
    2c: f3 0f 5e c1    divss %xmm1,%xmm0 
    30: f3 0f 11 45 f4   movss %xmm0,-0xc(%rbp) 
    [...] 

Gli interi vengono spostati nello stack, e poi convertiti in carri che sono memorizzati in registri MMX. Nuovi oggetti? Discutibile; in memoria: piuttosto no (dipende da cosa è la memoria, per me la memoria dovrebbe essere indirizzabile).

Se il compilatore di memorizzare correttamente le variabili (ad esempio, al fine di evitare problemi di precisione con i registri più precisi), otteniamo la seguente:

g++ -O0 -c -g -ffloat-store cast_code.cpp risultati in

// identical to above 
    14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp) 
    int i2 = 2; 
    1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) 
    float f = i1/(float)i2; 
    // same conversion 
    22: f3 0f 2a 45 fc   cvtsi2ssl -0x4(%rbp),%xmm0 

    // but then the result is stored on the stack. 
    27: f3 0f 11 45 f4   movss %xmm0,-0xc(%rbp) 

    // same for the second value (which undergoes an implicit conversion). 
    2c: f3 0f 2a 45 f8   cvtsi2ssl -0x8(%rbp),%xmm0 
    31: f3 0f 11 45 f0   movss %xmm0,-0x10(%rbp) 
    36: f3 0f 10 45 f4   movss -0xc(%rbp),%xmm0 
    3b: f3 0f 5e 45 f0   divss -0x10(%rbp),%xmm0 
    40: f3 0f 11 45 ec   movss %xmm0,-0x14(%rbp) 

E 'un po' doloroso vedere come i1 viene spostato dal registro alla memoria a 27 e poi di nuovo nel registro a 36 in modo che la divisione possa essere eseguita a 3b.

In ogni caso, spero che sia d'aiuto.

+0

Grazie, è stato molto utile –

Problemi correlati