2010-12-21 7 views
8

Ostatnio natknąłem się na następującym fragmencie, który jest próbą zapewnienia wszystkich bajtów i (NAD nie więcej) są dostępne jako pojedyncze elementy c:Czy ten związek działałby, gdyby char miał bardziej rygorystyczne wymagania dopasowania niż int?

union { 
    int i; 
    char c[sizeof(int)]; 
}; 

Teraz wydaje się to dobrym pomysłem, ale zastanawiam się, jeżeli standard dopuszcza przypadek, w którym wymagania dotyczące wyrównania dla char są bardziej restrykcyjne niż dla int.

Innymi słowy, czy możliwe jest czterobajtowe int, które musi być wyrównane na granicy czterech bajtów z jednobajtowym char (jest to jeden bajt, z definicji, patrz poniżej) wymagane do być wyrównane do szesnastobajtowej granicy?

Czy to podniosłoby użycie związku powyżej?

Dwie rzeczy do zapamiętania.

  1. Mówię konkretnie o tym, na co pozwala tutaj standard, a nie o tym, co zapewni rozsądny implementator/architektura.

  2. Używam terminu "bajt" w sensie ISO C, gdzie jest to szerokość char, niekoniecznie 8 bitów.

Odpowiedz

7

Brak typu może kiedykolwiek mieć ostrzejsze wymagania wyrównania niż jego wielkości (z powodu, jak działają tablice) i sizeof(char) jest 1.

W przypadku nie jest to oczywiste:

  • sizeof(T [N]) jest sizeof(T)*N .
  • sizeof jest w jednostkach char; wszystkie typy są reprezentowane jako stała liczba bajtów (char), których liczba jest ich wielkością. Aby uzyskać szczegółowe informacje, patrz 6.2.6 (Reprezentacja typów).
  • Biorąc pod uwagę T A[2];, (char *)&A[1] - (char *)&A[0] jest równa sizeof A[0].
  • Dlatego wymóg wyrównanie dla T jest nie większa niż sizeof(T) (w rzeczywistości dzieli sizeof(T))
+0

Będziesz musiał zacytować ISO, aby mnie przekonać na tym, R. Jaka szczególna cecha tablic nie zadziałałaby, gdybyś automatycznie skalował "a [i]" i "a + i", używając raczej wyrównania niż Rozmiar? – paxdiablo

+0

@paxdiablo: To nie zadziałałoby. '(void *) a + i * sizeof (* a)' –

+1

@ sharth - To i tak nie działa - arytmetyka wskaźnika na 'void *' jest niedozwolona. –

1

Wystarczy popatrzeć na this thread. Tam zakwestionowałem użyteczność związków C i są tam interesujące spostrzeżenia. Ważną rzeczą jest to, że Standard nie zapewnia w ogóle wyrównania różnych pól!

EDYCJA: paxdiablo, zauważyłeś, że byłeś jednym z chłopaków odpowiadających na to pytanie, więc powinieneś być zaznajomiony z tym ograniczeniem.

Powiązane problemy