2016-03-17 8 views
9

Sort of related to my previous question:Gli elementi array contano come una sequenza iniziale comune?

Gli elementi degli array vengono conteggiati come una sequenza iniziale comune?

struct arr4 { int arr[4]; }; 
struct arr2 { int arr[2]; }; 

union U 
{ 
    arr4 _arr4; 
    arr2 _arr2; 
}; 

U u; 
u._arr4.arr[0] = 0; //write to active 
u._arr2.arr[0]; //read from inactive 

Secondo this cppreference page:

In un'unione standard disposizione con un membro attivo della non unione tipo di classe T1, è permesso di leggere un non-statico membro di dati m di un'altra unione membro di classe non unione tipo T2 fornito m fa parte della sequenza iniziale comune di T1 e T2 ....

Questo sarebbe legale, o sarebbe anche punire tipo illegale?

+1

Senza alcun argomento credo sia legale. – knivil

risposta

4

C++ 11 dice (9.2):

Se un sindacato standard di layout contiene due o più struct standard di layout che condividono una sequenza iniziale comune, e se l'oggetto dell'unione standard di layout attualmente contiene una di queste strutture di layout standard, è consentito per ispezionare la parte iniziale comune di ognuna di esse. Due strutture di layout standard condividono una sequenza iniziale comune se i membri corrispondenti dispongono di tipi di layout compatibili e nessuno dei due è un campo di bit o entrambi campi di bit con la stessa larghezza per una sequenza di uno o più membri iniziali .

Quanto alla questione se le matrici di dimensioni diverse formano una sequenza iniziale comune valido, 3,9 dice:

Se due tipi T1 e T2 sono dello stesso tipo, quindi T1 e T2 sono tipi di layout compatibili

Questi array non sono dello stesso tipo, quindi questo non si applica. Non ci sono ulteriori eccezioni speciali per gli array, quindi gli array potrebbero non essere compatibili con il layout e non formare una sequenza iniziale comune.

In pratica, però, so di un compilatore (GCC) che:

  • ignora la regola "comune sequenza iniziale", e
  • permette digitare punning comunque, ma solo quando gli accessi sono "tramite il tipo di unione "(come nel tuo esempio), nel qual caso la regola" sequenza iniziale comune "è obbedita indirettamente (perché una" sequenza iniziale comune "implica un layout iniziale comune sulle architetture supportate dal compilatore).

Sospetto che molti altri compilatori adottino un approccio simile. Nel tuo esempio, in cui digiti tramite l'oggetto union, questi compilatori ti daranno il risultato atteso - la lettura dal membro inattivo dovrebbe darti un valore scritto tramite il membro inattivo.

+1

Ma gli array fanno parte di 'struct' e quindi sono membri. – knivil

+0

@davmac Leggi la domanda - 'U' contiene un' arr4' e uno 'arr2', mentre questi nomi possono essere confusi, questi sono definiti come' struct' appena sopra. – Holt

+0

@Holt sì, l'ho letto male. Tuttavia, la risposta finale ("no") è la stessa. Ho modificato la mia risposta sopra per spiegare perché. – davmac

Problemi correlati