Dlaczego warto używać typedefs dla struktur?

12

w C (ANSI, C99 itp.), struktury żyją we własnej przestrzeni nazw. Struktura połączonej listy może wyglądać mniej więcej tak:

struct my_buffer_type {
   struct my_buffer_type * next;
   struct my_buffer_type * prev;
   void * data;
};

Wydaje się jednak całkiem naturalne, że większość programistów C automatycznie wpisuje te struktury w następujący sposób

typedef struct tag_buffer_type {
   struct tag_buffer_type * next;
   struct tag_buffer_type * prev;
   void * data;
} my_buffer_type;

A następnie odwołaj się do struktury jak normalny typ, tj get_next_element(my_buffer_type * ptr).

Teraz moje pytanie brzmi: czy jest tego konkretny powód?

Wikipedia mówi http://en.wikipedia.org/wiki/Typedef#Usage_concerns

Niektórzy ludzie są przeciwni szerokiemu użyciu typedefs. Większość argumentów koncentruje się na pomyśle, że typedefs po prostu ukrywa rzeczywisty typ danych zmiennej. Na przykład Greg Kroah-Hartman, haker i dokumentator jądra Linuksa, odradza ich używanie do czegokolwiek poza deklaracjami prototypów funkcji. Twierdzi, że ta praktyka nie tylko niepotrzebnie zaciemnia kod, ale może również powodować, że programiści przypadkowo niewłaściwie wykorzystują duże struktury, uważając je za typy proste [4].

Inni twierdzą, że użycie typedefs może ułatwić utrzymanie kodu. K&R twierdzi, że istnieją dwa powody, dla których warto użyć typedef. Po pierwsze, zapewnia sposób na zwiększenie przenośności programu. Zamiast zmieniać typ wszędzie, gdzie pojawia się w plikach źródłowych programu, należy zmienić tylko jedną instrukcję typedef. Po drugie, typedef może ułatwić zrozumienie złożonej deklaracji.

Osobiście zastanawiam się, czy nie ma wystarczającej korzyści z posiadania oddzielnej structprzestrzeni nazw, aby czasami nie używać struktur o typie zdefiniowanym, a ponieważ istnieje kilka kultur programowania C (z mojego doświadczenia wynika, że ​​programowanie w Windows C ma inne tradycje niż programowanie w Linuxie C) tradycje, których nie znam.

Następnie interesują mnie względy historyczne (poprzednicy, pierwsze wersje C).

wirrbel
źródło
4
Celem a typedef jest ukrycie rzeczywistego typu zmiennej. Weźmy time_tjako przykład: jeśli ludzie będą się poruszać, używając bazowej liczby całkowitej, zmiana w implementacji, taka jak ta, która będzie wymagana w 2038 r., Złamie strasznie dużo kodu. F Jeśli ludzie używają struktur, nie rozumiejąc dlaczego, to jest to awaria programisty, a nie konstrukcji.
Blrfl

Odpowiedzi:

14

Pracowałem nad dużym projektem, który intensywnie wykorzystywał struktury typedef'd. Zrobiliśmy to z kilku powodów. Należy pamiętać, że była to wersja sprzed C99 i segregacja przestrzeni nazw.

  1. Łatwiej było pisać my_buffer_type *bufferzamiast struct tag_buffer_type *bufferi dla wielkości bazy kodu (1M + loc) zrobiło to dużą różnicę.

  2. Wyodrębnia strukturę na obiekt. Zamiast skupiać się na każdej pojedynczej zmiennej w strukturze, skupilibyśmy się na reprezentowanym przez nią obiekcie danych. Ta abstrakcja doprowadziła do ogólnie bardziej użytecznego i łatwiejszego do napisania kodu.

    • Myślę, że jest to sprzeczne z cytatem przypisanym przez Grega Kroah-Hartmana. FWIW, ten projekt był aplikacją klient / serwer, a nie jądrem, więc z pewnością należy wziąć pod uwagę kilka różnych względów.
  3. Traktowanie struktury jako obiektu umożliwiło nam także lepsze enkapsulowanie informacji. Przegląd kodu wychwycił kilka sytuacji, w których nowszy programista naruszyłby zasady enkapsulacji, które wprowadziliśmy. Użycie struktur typedef'd sprawiło, że naruszenia te stały się oczywiste.

  4. Przenośność była problemem, ponieważ pisaliśmy na pół tuzina platform z serwerem i kilka innych z klientem.


źródło
5

Za każdym razem zamiast pisać

struct my_buffer_type *buffer;

jeśli możesz typedef, możesz użyć bezpośrednio

my_buffer_type *buffer;

typedefGłównym zastosowaniem jest zmniejszenie liczby naciśnięć klawiszy wymaganych do pisania kodu i zwiększenie czytelności.

AMohan
źródło
masz rację, ale opisałem ten fakt już w moim pytaniu.
wirrbel,