2016-07-24 14 views
99

Jeśli chcesz używać Qt, musisz objąć quint8, quint16 i tak dalej.Dlaczego wszyscy wpisują się w typowe typy C?

Jeśli chcesz użyć GLib, trzeba powitać guint8, guint16 i tak dalej.

Na Linuxu32, s16 i tak dalej.

uC/OS definiuje SINT32, UINT16 i tak dalej.

A jeśli musisz użyć jakiejś kombinacji tych rzeczy, lepiej przygotuj się na kłopoty. Ponieważ na komputerze użytkownika u32 będzie typedef d przez long i quint32 będzie typedef d przez int, a kompilator złoży skargę na.

Dlaczego każdy to robi, jeśli jest <stdint.h>? Czy jest to jakaś tradycja dla bibliotek?

+0

Dla mnie ważniejsze pytanie nie brzmi "dlaczego po prostu nie używają' stdint.h'? ", Ale raczej byłoby, dlaczego ktokolwiek np. używaj 'UINT16' lub' quint16' zamiast po prostu zwykłego 'unsigned short' w pierwszej kolejności? Na * który dokładnie kompilator * może to spowodować, że je zawiedzie? – Mehrdad

+8

@Mehrdad w programowaniu mikrokontrolerów możesz mieć wiele różnych rzeczy. Na AVR Mega na przykład (i konsekwentnie na słynnej Arduino) int jest 16 bitowe. To może być paskudna niespodzianka. Moim zdaniem "niepodpisany krótki" wymaga więcej wysiłku pisania. I zawsze mnie to zasmuciło używając "unsigned char" dla oktetu bajt. Niepodpisana postać, naprawdę? – Amomum

+0

Tak, jestem tego świadomy, ale mówiłem o 'short', a nie' int'. Czy znasz platformę, na której 'short' nie działałby, ale' S8' i 'S16' oba? Wiem, że to całkiem możliwe w teorii, ale jestem prawie pewien, że większość bibliotek, w których widzę takie typy, nigdy nie byłaby celem takich platform. – Mehrdad

Odpowiedz

78

stdint.h nie istniał z powrotem, gdy biblioteki te były rozwijane. Tak więc każda biblioteka miała własne sny typedef.

+1

Dlaczego wszyscy nie wzięli typów z innej biblioteki lub pliku nagłówkowego? Dlaczego Glib (który został opracowany na Linuksie) nie korzystał z Linux-a? – Amomum

+3

I dobrze, przypuszczam, że brak stdint.h jest dobrym powodem, ale dlaczego nawet dzisiaj te typedefs są nad int, długo i tak dla, a nie ponad typami stdint? Oznaczałoby to, że są wymienne co najmniej: – Amomum

+1

@Amomum Usuwanie 'quint8' (na przykład) spowodowałoby złamanie istniejącego kodu. Dla wszystkich, które znamy, 'quint8' może być typedef dla standardowego 8-bitowego typu unsigned integer' uint8_t'. – Kusalananda

39

W przypadku starszych bibliotek jest to potrzebne, ponieważ dany nagłówek (stdint.h) nie istnieje.

Wciąż jednak występuje problem: typy te (uint64_t i inne) to opcjonalna funkcja w standardzie. Tak więc zgodna implementacja może nie zostać dostarczona wraz z nimi - i w związku z tym zmusić biblioteki do dalszego ich uwzględniania w dzisiejszych czasach.

+29

To jest po prostu straszne i sprawia, że ​​chcę płakać: C – Amomum

+12

Typy 'uintN_t' są opcjonalne, ale typy' uint_leastN_t' i 'uint_fastN_t' nie są. – Kusalananda

+0

@Kusalananda wydaje się odpowiadać mojej odpowiedzi – Ven

12

stdint.h został ujednolicony od 1999 roku. Jest bardziej prawdopodobne, że wiele aplikacji definiuje (skutecznie alias) typy, aby zachować częściową niezależność od bazowej architektury maszyny.

Zapewniają one deweloperom pewność, że typy używane w ich aplikacji pasują do ich specyficznych dla projektu założeń dotyczących zachowania, które mogą nie być zgodne ze standardem językowym lub implementacją kompilatora.

Praktyka jest odzwierciedlana w zorientowanym obiektowo wzorcu projektowym Façade i jest często nadużywana przez programistów niezmiennie piszących klasy opakowujące dla wszystkich importowanych bibliotek.

Gdy kompilatory były o wiele mniej standardowe, a architektura maszyn mogła różnić się od 16-bitowych, 18-bit do 36-bit mainframe o długości słowa, było to o wiele bardziej istotne. Ta praktyka jest teraz znacznie mniej istotna w świecie, w którym spotykają się 32-bitowe systemy wbudowane ARM. Pozostaje problemem dla low-endowych mikrokontrolerów z mapami pamięci odd.

+1

Zgoda, 'stdint.h' został ujednolicony od 1999 roku, ale od kiedy jest dostępny w praktyce? Ludzie przeciągają swoje stopy, wdrażając i przyjmując nowe standardy, a podczas tego długiego okresu przejściowego stare metody wciąż są koniecznością. –

+1

Jednym z nieprzyjemnych problemów z 'stdint.h' jest to, że nawet na platformach, gdzie np. 'long' i' int32_t' mają taki sam rozmiar i reprezentację, nie ma wymogu, aby rzucanie 'int32_t *' na 'long *' przyniosło wskaźnik, który może niezawodnie uzyskać dostęp do 'int32_t'. Nie mogę uwierzyć, że autorzy Standardu uważali za oczywiste, że typy kompatybilne z układem powinny być kompatybilne z aliasami, ale ponieważ nie zawracali sobie tym głowy, autorzy gcc i klanu IIRC uważają, że język byłby lepszy, ignorując aliasing nawet w przypadkach, w których jest to oczywiste. – supercat

+1

@supercat - to chyba warto przesłać jako errata do komisji C ... ponieważ to jest * bezmyślnie głupie *, delikatnie mówiąc – LThode

3

Masz więc moc typedef char do int.

Jeden z "horrorów kodujących" wspomniał, że nagłówek jednej z firm miał punkt, w którym programista chciał uzyskać wartość boolowską, a char był rodzajem logicznym rodzimego dla zadania, i tak napisał typedef bool char. Później ktoś znalazł liczbę całkowitą, która jest najbardziej logicznym wyborem, i napisał: typedef bool int.Wynik, na wieki przed Unicode, był praktycznie typedef char int.

Myślę, że całkiem sporo myślenia przyszłościowego, kompatybilności do przodu.

Powiązane problemy