2015-03-11 16 views
5

In base allo http://en.cppreference.com/w/cpp/language/reinterpret_cast, è noto che reinterpret_cast un puntatore a un integrale di dimensioni sufficienti e al rendimento di ritorno lo stesso valore. Mi chiedo se il contrario sia anche vero per gli standard. Vale a dire, fa reinterpret_cast un integrale di un tipo di puntatore di dimensioni sufficienti e il rendimento a ritroso ha lo stesso valore?Reinterpret_casting un integrale a un tipo di puntatore e back restituisce lo stesso valore?

+0

No, questo non è garantito. Ad esempio, diversi numeri interi possono essere convertiti nello stesso indirizzo. –

+0

@ n.m. Potresti dare un esempio concreto? Si noti che 'reinterpret_cast' è usato qui per eseguire la conversione. – Lingxi

+0

Prendere l'architettura 8086. Il numero intero 0x10002000L interpretato come 0x1000: 0x2000 (segmento e offset) corrisponde all'indirizzo fisico 0x12000. Così fa il numero intero 0x12000000L. Nulla impedisce al compilatore di convertire 0x10002000L in 0x1200: 0x0000 segmento e offset, quindi convertirlo nuovamente in 0x12000000L. Nei vecchi tempi questo era noto come enorme normalizzazione del puntatore. –

risposta

0

No, questo non è garantito dallo standard. Citando tutte le parti di C++ 14 (n4140) [expr.reinterpret.cast] che riguardano puntatore – numeri interi, sottolineatura mia:

4 Un puntatore può essere convertito esplicitamente qualsiasi tipo integrale abbastanza grande per contenerla . La funzione di mappatura è definita dall'implementazione. [Nota: Si intende che non sorprenda coloro che conoscono la struttura di indirizzamento della macchina sottostante. -end note] ...

5 Un valore di tipo integrale o tipo di enumerazione può essere convertito in modo esplicito in un puntatore. Un puntatore ha convertito in un numero intero di dimensioni sufficienti (se ne esiste uno nell'implementazione) e di nuovo nello stesso tipo di puntatore avrà il suo valore originale; I mapping tra i puntatori e gli interi sono altrimenti definiti dall'implementazione. [Nota: Salvo quanto descritto in 3.7.4.3, il risultato di tale conversione non sarà un valore di puntatore sicuro derivato . -end nota]

Quindi, a partire da un valore integrale e convertirlo in un puntatore e posteriore (supponendo che non problemi di dimensione) dipende dall'implementazione. Il che significa che devi consultare la documentazione del tuo compilatore per sapere se un simile round trip conserva o meno i valori. In quanto tale, non è certamente portatile.

0

Ho esattamente questo problema nella libreria esportando i puntatori agli oggetti come identificativi opachi e ora il tentativo di recuperare questi puntatori da chiamate esterne non funziona con le vecchie CPU x86 (al momento di Windows 98). Quindi, mentre possiamo aspettarci questo comportamento, questo è falso in generale. Nella 386-CPU l'indirizzo è composto da puntatori sovrapposti quindi l'indirizzo di qualsiasi posizione di memoria non è univoco, e ho trovato che la conversione non ripristina il valore originale.