2013-02-18 18 views
8

Jestem nowym użytkownikiem jądra systemu Linux. Czytam plik ioctl.h nie natknąłem makro _IOC_TYPECHECK(t), który wygląda tak:Co oznacza sizeof (int [1])?

#define _IOC_TYPECHECK(t) \ 
     ((sizeof(t) == sizeof(t[1]) && \ 
      sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ 
      sizeof(t) : __invalid_size_argument_for_IOC) 

Czy możesz mi wyjaśnić ten kod? W tym kodzie co oznacza sizeof(t[1])?

Odpowiedz

7

Służy do sprawdzania poprawności trzeciego parametru do makr _IOR/_IOW/_IOWR, który powinien być typem. Sprawdza, czy parametr jest rzeczywiście typem (a nie zmienną lub liczbą), i w przeciwnym razie powoduje błąd kompilatora lub linkera.

  • Jeśli t jest typu, to t[1] jest typu "tablica 1 t". Ten typ ma ten sam rozmiar co t, a zatem sizeof(t) == sizeof(t[1]) jest prawdziwy.

  • Jeśli t jest liczbą, to nie można skompilować pliku sizeof(t).

  • Jeśli t jest prosty zmienna (bez tablicy), po czym t[1] powoduje błąd kompilatora.

  • Jeśli t jest zmienną tablicową, sizeof(t) == sizeof(t[1]) będzie fałszywe, a błąd linkera będzie spowodowane (bo __invalid_size_argument_for_IOC nie jest określona).

Wyrażenie sizeof(t) < (1 << _IOC_SIZEBITS) sprawdza, czy wielkość typu t nie przekracza maksymalny dozwolony dla ioctl i powoduje ten sam błąd linkera inaczej.

Nadal istnieją pewne nieważne przypadki, które nie zostaną przechwycone przez to makro - na przykład, gdy t jest wskaźnikiem do wskaźnika.

+0

"Jeśli' t' jest zmienną tablicową, 'sizeof (t) == sizeof (t [1])' będzie fałszywe "czy to naprawdę zawsze prawda? –

+0

@AndreasGrapentin: Nie dla tablicy z jednym elementem, ale może pojawić się ostrzeżenie kompilatora o indeksowaniu tablicy poza granicami. – interjay

3

Oznacza to samo, co wszystkie inne zastosowania sizeof. Oblicza wielkość wyrażenia.

W tym konkretnym przypadku podejrzewam, że kontrola ma na celu zapewnienie pewnej własności t (która powinna być nazwą typu, a nie zmienną), którego nie znam z kontekstu ... Być może jest to możliwe traktować go jako wskaźnik (potrzebny do indeksowania tablicy), który wykluczałby niektóre typy. Komentarz obok makra mówi: /* provoke compile error for invalid uses of size argument */, który wydaje się wspierać tę teorię.

Należy pamiętać, że sizeof to operator, a nie funkcja. Nawias nie jest potrzebny, chyba że chcesz obliczyć rozmiar typu bezpośrednio, a następnie są częścią wyrażenia (jest to wyrażenie rzutowania). Więc to może być napisane sizeof t == sizeof t[1] && ..., lub może (sizeof t == sizeof t[1]) dla jasności.

Jest to bardzo dobry styl do użycia, ponieważ "blokuje" rozmiar obliczany do odpowiedniej macierzy, zamiast powtarzać typ t. Tak więc, jeśli typ miał ulec zmianie, wyrażenie automatycznie dostosowuje się i nadal oblicza właściwą rzecz.

Wielu programistów C wydaje się preferować posiadanie nawiasów wokół argumentów do sizeof we wszystkich przypadkach, z jakiegoś powodu.

+1

't' tutaj ma być typem, a nie zmienną. To trzeci parametr dla makr [_IOR] (http://h30097.www3.hp.com/docs/dev_doc/DOCUMENTATION/HTML/DDK_R2/DOCS/HTML/MAN/MAN9/0028___R.HTM)/_IOW/_IOWR. – interjay

+0

Nie wiedziałem, że parametry 'sizeof' były opcjonalne, z wyjątkiem typu; lub, że są technicznie obsadą w tym przypadku. +1 tylko po to! – Chowlett

+1

", a następnie są częścią wyrażenia". Nie jestem pewien, czy rozumiem, co masz na myśli. Identyfikator typu (np. 'Int') nie musi mieć nawiasów i nie jest wyrażeniem, ale nawiasy są wymagane w' sizeof (int) ', ponieważ są to reguły gramatyczne ... lub czy dostajesz coś innego? To także nie jest obsada. –