2011-10-17 8 views
5

Se ho una struct come questo:struct layout di componenti di memoria

struct S { 
    ANY_TYPE a; 
    ANY_TYPE b; 
    ANY_TYPE c; 
} s; 

Posso tranquillamente assumere che le seguenti assunzioni saranno sempre vero su tutte le piattaforme?

((char *)&s.a) < ((char *)&s.c) 
((char *)&s.a + sizeof(s.a) + sizeof(s.b)) <= ((char *)&s.c) 

Anche in C++?

+0

@VJo: Puoi spiegare come? –

+0

Che cos'è un esempio di ANY_TYPE in cui non è presente? –

+0

Perché vuoi? Il punto delle strutture è di eliminare questo tipo di giocoleria. – Beta

risposta

3

Sì, almeno in C. Il compilatore è libero di inserire padding dopo ogni membro della struttura ma non deve riordinare i membri.

Inoltre, non deve inserire il riempimento prima del primo membro.

Da C99, 6.7.2.1:

13/ Da un oggetto struttura, i membri non bit di campo e le unità in cui bit-campi risiedere avere indirizzi che aumentano nell'ordine in cui essi sono dichiarati Un puntatore a un oggetto di struttura, opportunamente convertito, punta al suo membro iniziale (o se quel membro è un campo di bit, quindi all'unità in cui risiede) e viceversa. Potrebbe esserci un padding senza nome all'interno di un oggetto struttura, ma non all'inizio.

15/ Potrebbe esserci un riempimento senza nome alla fine di una struttura o unione.

+0

Ri * Deve inoltre non inserire il padding prima del primo membro. *: Ciò renderebbe la maggior parte dei compilatori non conformi. Aggiungere un vtable prima del primo membro è un approccio molto comune all'implementazione del polimorfismo. –

+5

@DavidHammen Prima di tutto, i vtables sono un dettaglio di implementazione di C++, non C. In secondo luogo, il requisito di no-padding-before-first-member è solo per POD (Plain Old Data). Le classi con vtables non sono POD e quindi è permesso avere a.o. un puntatore vtable prima del primo membro di dati. – Sjoerd

1

In C++ si può essere certi che queste ipotesi saranno valide. In una struttura come questa, al compilatore non è permesso cambiare l'ordine dei membri.

0

Sì, per impostazione predefinita i compilatori C++ non sono autorizzati a spostarsi attorno a elementi in una struttura che rende banalmente veritiere entrambe le istruzioni.

0
  1. Sì (a patto che sizeof (quals._tipo) non è 0. Alcuni compilatori permettono, che è non-standard - vedi Can sizeof return 0 (zero)). Saresti al sicuro con < = o semplicemente assumerai un compilatore standard.

E in C++ troppo.

Il confronto tra puntatori ha senso solo all'interno di matrici e strutture/classi, in generale.

4

Questo è vero per una struttura, ma cambia in C++ non appena si introducono gli specificatori di accesso. Il compilatore può riordinare interi blocchi delimitati da specificatori di accesso.

+0

È proprio vero?Lo standard dice che le variabili membro vengono inizializzate nell'ordine in cui sono elencate nella classe. Suppongo che il loro ordine relativo non possa essere cambiato grazie a quello. – Xeo

+2

@Xeo Vedere (ad esempio) qui http://stackoverflow.com/questions/4883655/access-specifier-in-c/4883764#4883764 Purtroppo questa risposta non ha virgolette standard. Proverò a fornire alcuni. Riguardo all'inizializzazione: l'inizializzazione è indipendente dall'ordinazione della memoria. – pmr

Problemi correlati