2015-04-24 10 views
5

Questo non è un duplicato di questoquestion, Ho letto le risposte e ho ancora alcune domande su questo argomento.allocazione della memoria per i campi pubblici e privati ​​- GCC modo

ho provato alcune classi come questo:

class A { 
private: 
    int b; 

public: 
    char c; 
    int a; 

private: 
    char e; 
}; 

e ho visto che i campi vengono memorizzate come se non ci fosse l'accesso-specificatore, questo non è sbagliato in quanto:

N3376 (il primo post C++ 11 draft) 9.2 [class.mem]/13:

membri di dati non statici di un (non-union) classe con lo stesso controllo di accesso (clausola 11) vengono assegnati in modo che i membri successivi abbiano indirizzi più elevati all'interno di un oggetto classe. L'ordine di allocazione di membri di dati non statici con controlli di accesso diversi non è specificato. I requisiti di allineamento dell'implementazione potrebbero far sì che due membri adiacenti non vengano allocati immediatamente uno dopo l'altro; quindi potrebbero essere necessari requisiti per lo spazio per la gestione di funzioni virtuali (10.3) e classi di base virtuali (10.1).

Quello che ancora non capisco è questo:

L'ordine di assegnazione dei membri di dati non statici con controllo di accesso di ff erenti è non specificata fi cato.

Che cosa si intende per non specificato, GCC certamente hanno un modo di fare questo, essi non solo fare a caso immagino ... Non vogliono che l'utente lo sappia? Oppure ci sono così tanti modi a seconda delle opzioni forse?

Perché tutti gli esempi che ho provato, ho avuto lo stesso ordine come dichiarato nel mio file (+ padding)

Sto usando gcc 4.9.2, Qualcuno sa se GCC specificato il loro modo di fare questo?

Ho bisogno di sapere questo perché sto creando un programma che calcola il padding tra tutti i campi, il programma funziona con strutture che non hanno specificatori di accesso per il momento. Dovrò trovare un modo per farlo quando c'è diversi blocchi di accessibilità

+2

Se qualcosa è "non specificato" o "specifico dell'implementazione" significa che il compilatore può fondamentalmente fare ciò che vuole, a condizione che non infranga qualcos'altro. –

+3

http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior – Mat

+3

@JoachimPileborg: non del tutto: l'implementazione definita significa che l'implementazione è libera di scegliere, ma deve documentare la scelta all'utente . Non specificato significa che l'utente non ha il diritto di sapere. In questo esempio, il compilatore mescola il layout della classe in modo diverso durante ogni compilazione e ciò sarebbe conforme. –

risposta

3

By non specificato significa che il compilatore è:

  • libero di prendere qualsiasi decisione che vuole
  • e non è richiesto per documentarlo

E mezzi definiti dall'implementazione, il compilatore è libero di prendere qualsiasi decisione ed è tenuto a documentarlo..


Se si considera questa classe (leggermente modificato la propria versione):

class X { 
private: 
    int b; 
    int z; 

public: 
    char c; 
    int a; 

private: 
    char e; 

public: 
    int d; 
}; 

poi il testo dal spec significa:

  • E 'garantito che
    • &c < &a — appartengono entrambi a stesso controllo di accesso.
    • &b < &z — entrambi appartengono allo stesso controllo di accesso.
  • è altresì garantito che
    • &z < &e — entrambi appartengono allo stesso controllo di accesso, con interleaving.
    • &a < &d — entrambi appartengono allo stesso controllo di accesso, con interleaving.
  • È non garantito che:
    • &z < &c — entrambi appartengono al controllo di accesso differente.
    • &a < &e — entrambi appartengono a diversi controlli di accesso.

Ho visto codice che utilizza l'accesso specificatore per ciascuna variabile, in modo che il compilatore può ri-organizzare in modo da rendere il formato come più piccolo possibile.

+0

Penso che '& z <& e' e' & a <& d' siano garantiti, è solo per diversi specificatori che non è specificato –

+0

@Othman: lo pensavo anche io. Ma ho sentito l'argomento che sono considerati diversi anche se sono uguali a * tipo * e l'argomento è che aiuta il compilatore a ottimizzare '(sizeof (X))' il più possibile. – Nawaz

+1

@Othman C'è stato un cambiamento tra C++ 03 e C++ 11 per questo. C++ 03 garantisce solo l'ordine tra "membri di dati non statici di una classe (non sindacata) dichiarata senza un identificatore di accesso * intermedio *"; C++ 11 garantisce l'ordine tra tutti i membri di dati con lo stesso controllo di accesso. –