2016-03-17 24 views
9

Sortuj powiązane z my previous question:Czy elementy tablic liczą się jako wspólna początkowa sekwencja?

Czy elementy tablic liczą się jako wspólna początkowa sekwencja?

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 

Według this cppreference page:

W związku standardowego układu z aktywnym członkiem non-Union Typ klasa T1, dopuszcza się czytać non-statycznego elementu danych M innej unii członek klasy niezwiązanej T2, pod warunkiem, że m jest częścią wspólnej początkowej sekwencji T1 i T2 ....

Czy byłoby to zgodne z prawem, czy też byłoby to nielegalne wykroczenie typu?

+1

Bez żadnych argumentów uważam, że jest legalne. – knivil

Odpowiedz

4

C++ 11 mówi, (9,2)

Jeśli związek o standardowej układ zawiera dwa lub więcej konstrukcjom standardowego układu, które mają wspólną sekwencję początkową, i jeśli związków obiektu standardowego układu aktualnie zawiera jeden z tych standardowych układów, dozwolony jest w celu sprawdzenia wspólnej początkowej części dowolnego z nich. Dwie struktury o standardowym układzie mają wspólną początkową sekwencję , jeśli odpowiadający element ma zgodny z układem typ i żaden z elementów nie jest polem bitowym lub oba są polami bitowymi o tej samej szerokości dla sekwencji jednego lub większej liczby początkowych elementów .

Jako, czy matryce o różnej wielkości tworzą ważny wspólny początkową sekwencję, 3,9 mówi:

Jeśli dwa typy T1 i T2 są tego samego typu, a następnie T1 i T2 układ zgodny rodzaje

Te tablice nie są tego samego typu, więc nie ma to zastosowania. Nie ma specjalnego dodatkowego wyjątku dla tablic, więc tablice mogą nie być kompatybilne z układem i nie tworzą wspólnej początkowej sekwencji.

W praktyce, choć wiem kompilator (GCC), które:

  • ignoruje zasadę „wspólnego początkowy sekwencji” i
  • pozwala wpisać paronomazja tak, ale tylko wtedy, gdy dostępy są „poprzez typ unii "(jak w twoim przykładzie), w którym to przypadku reguła" wspólnej początkowej sekwencji "jest stosowana pośrednio (ponieważ" wspólna początkowa sekwencja "implikuje wspólny początkowy układ na architekturach obsługiwanych przez kompilator).

Podejrzewam, że wiele innych kompilatorów stosuje podobne podejście. W twoim przykładzie, gdzie typujesz kalambur za pomocą obiektu unii, takie kompilatory dadzą ci oczekiwany rezultat - odczyt od nieaktywnego członka powinien dać ci wartość zapisaną przez nieaktywnego członka.

+1

Ale tablice są częścią 'struct' i dlatego są członkami. – knivil

+0

@davmac Przeczytaj pytanie - 'U' zawiera jedno' arr4' i jedno 'arr2', podczas gdy te nazwy mogą być mylące, są zdefiniowane jako' struct' tuż powyżej. – Holt

+0

@Holt tak, błędnie przeczytałem. Jednak ostateczna odpowiedź ("nie") jest taka sama. Poprawiłem powyższą odpowiedź, aby wyjaśnić, dlaczego. – davmac