I membri class / struct vengono sempre creati in memoria nell'ordine in cui sono stati dichiarati?

StackOverflow https://stackoverflow.com/questions/281045

  •  07-07-2019
  •  | 
  •  

Domanda

Questa è una domanda che è stata sollevata dalla risposta di Rob Walker here .

Supponiamo che dichiari una classe / struttura in questo modo:

struct
{ 
    char A;
    int B;
    char C;
    int D;
};

È sicuro presumere che questi membri saranno dichiarati esattamente in quell'ordine in memoria, o è una cosa dipendente dal compilatore? Lo sto chiedendo perché avevo sempre supposto che il compilatore potesse fare quello che voleva con loro.

Questo porta alla mia prossima domanda. Se l'esempio sopra riportato causa problemi di allineamento della memoria, perché il compilatore non può semplicemente trasformarlo in qualcosa del genere implicitamente:

struct
{ 
    char A;
    char C;
    int B;
    int D;
};

(chiedo principalmente di C ++, ma sarei interessato anche a sentire la risposta C)

Argomenti correlati

È stato utile?

Soluzione

C99 & # 167; 6.7.2.1 clausola 13 afferma:

  

All'interno di un oggetto struttura, il   non-bit - & # 64257; membri eld e le unità in   quale bit - & # 64257; i campi risiedono hanno indirizzi   quell'aumento nell'ordine in cui   sono dichiarati.

e continua a dire qualcosa in più su imbottitura e indirizzi. La sezione equivalente di C89 è & # 167; 6.5.2.1.

C ++ è un po 'più complicato. Negli standard 1998 e 2003, vi è & # 167; 9.2 clausola 12 (clausola 15 in C ++ 11):

  

Membri di dati non statici di a   Classe (non sindacale) dichiarata senza un   sono gli identificatori di accesso intermedi   assegnato in modo che i membri successivi abbiano   indirizzi più alti all'interno di una classe   oggetto. L'ordine di assegnazione di   membri di dati non statici separati da un   L'identificatore di accesso non è specificato   (11.1). Allineamento di implementazione   i requisiti potrebbero causare due adiacenti   membri da non assegnare   immediatamente dopo l'altro; così potrebbe   requisiti di spazio per la gestione   funzioni virtuali (10.3) e virtuali   classi di base (10.1).

Altri suggerimenti

I membri dei dati sono disposti nell'ordine dichiarato. Il compilatore è libero di spaziare tra i padding per organizzare l'allineamento di memoria che gli piace (e scoprirai che molti compilatori hanno una barca che carica le opzioni di specifica di allineamento, utile se si mescolano bit compilati da programmi diversi).

Vedi anche Perché GCC non ottimizza le strutture? .


Sembra che questa risposta sia in qualche modo obsoleta per C ++. Impari qualcosa ogni giorno. Grazie, Nemanja.

Fondamentalmente, puoi contare su questo solo per le classi con un layout standard . A rigor di termini, il layout standard è una cosa C ++ 0x, ma in realtà sta solo standardizzando la pratica esistente /

Non posso parlare per C ++, ma in C l'ordine è garantito per essere lo stesso ordine in memoria dichiarato nella struttura.

A parte il riempimento per l'allineamento, nessun compilatore (di cui sono a conoscenza) non consente l'ottimizzazione della struttura per C o C ++. Non posso parlare per le classi C ++, in quanto potrebbero essere completamente un'altra bestia.

Considera che il tuo programma si interfaccia con il codice di sistema / libreria su Windows ma vuoi usare GCC. Dovresti verificare che GCC abbia usato un identico algoritmo di ottimizzazione del layout in modo che tutte le tue strutture siano imballate correttamente prima di inviarle al codice compilato da MS.

Mentre sfogliavo gli argomenti correlati a destra, ho guardato questa domanda . Immagino che questo possa essere un caso interessante quando si pensa a questi problemi (a meno che non sia più comune di quanto mi renda conto).

Per parafrasare, se hai una struttura in C che assomiglia a questa:

struct foo{};

e esegui la sottoclasse in questo modo in C ++ (usando un'unità di compilazione separata):

extern "C" foo;
struct bar: public foo{};

Quindi l'allineamento della memoria non sarà necessariamente lo stesso per i motivi aib menzioni (anche tra compilatori dello stesso fornitore).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top