Domanda

Ad esempio, se dichiaro una variabile long, posso presumere che sarà sempre allineata su un limite "sizeof(long)"?Lo dice la guida in linea di Microsoft Visual C++, ma è un comportamento standard?

qualche informazione in più:

UN.È possibile creare esplicitamente un intero disallineato (*bar):

char foo[5]

int * bar = (int *)(&foo[1]);

B.Apparentemente, #pragma pack() influisce solo su strutture, classi e unioni.

C.La documentazione di MSVC afferma che i tipi POD sono allineati alle rispettive dimensioni (ma è sempre o per impostazione predefinita ed è un comportamento standard, non lo so)

È stato utile?

Soluzione

Come altri hanno già detto, questo non fa parte dello standard e spetta al compilatore implementarlo come ritiene opportuno per il processore in questione.Ad esempio, VC potrebbe facilmente implementare requisiti di allineamento diversi per un processore ARM rispetto a quelli per i processori x86.

Microsoft VC implementa quello che viene sostanzialmente chiamato allineamento naturale fino alla dimensione specificata dalla direttiva #pragma pack o dall'opzione della riga di comando /Zp.Ciò significa che, ad esempio, qualsiasi tipo POD con dimensione inferiore o uguale a 8 byte verrà allineato in base alla sua dimensione.Qualunque cosa più grande verrà allineata su un limite di 8 byte.

Se è importante controllare l'allineamento per diversi processori e diversi compilatori, è possibile utilizzare una dimensione di imballaggio pari a 1 e riempire le proprie strutture.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

In questo codice, il padding1 La variabile esiste solo per assicurarsi che data2 sia naturalmente allineato.

Rispondi ad una:

Sì, ciò può facilmente causare dati disallineati.Su un processore x86, questo non fa affatto male.Su altri processori ciò può provocare un arresto anomalo o un'esecuzione molto lenta.Ad esempio, il processore Alpha genererebbe un'eccezione del processore che verrebbe rilevata dal sistema operativo.Il sistema operativo ispezionerebbe quindi l'istruzione e quindi svolgerebbe il lavoro necessario per gestire i dati disallineati.Quindi l'esecuzione continua.IL __unaligned la parola chiave può essere utilizzata in VC per contrassegnare l'accesso non allineato per programmi non x86 (ad es.forza).

Altri suggerimenti

Per impostazione predefinita, sì.Tuttavia, può essere modificato tramite pack() #pragma.

Non credo che lo standard C++ imponga alcun requisito al riguardo e lo lasci all'implementazione.

C e C++ non impongono alcun tipo di allineamento.Ma l'allineamento naturale è fortemente preferito da x86 e lo è necessario dalla maggior parte delle altre architetture di CPU e i compilatori generalmente fanno del loro meglio per mantenere felici le CPU.Quindi in pratica non vedrai un compilatore generare dati disallineati a meno che non gli giri davvero il braccio.

Sì, tutti i tipi sono sempre allineati almeno ai requisiti di allineamento.

Come potrebbe essere altrimenti?

Ma nota che la sizeof() di un tipo non è la stessa del suo allineamento.

È possibile utilizzare la seguente macro per determinare i requisiti di allineamento di un tipo:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )

Dipende dal compilatore, dai pragma e dal livello di ottimizzazione.Con i compilatori moderni puoi anche scegliere l'ottimizzazione del tempo o dello spazio, che potrebbe modificare anche l'allineamento dei tipi.

Generalmente sarà perché leggerlo/scriverlo è più veloce in questo modo.Ma quasi tutti i compilatori hanno un interruttore per disattivarlo.In gcc è -maligno-???.Con gli aggregati vengono generalmente allineati e dimensionati in base ai requisiti di allineamento di ciascun elemento al loro interno.

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