2009-03-30 10 views
8

Zawsze stosowane typedef w osadzonym programowania, aby uniknąć typowych błędów:Inteligentne typedefs

int8_t - 8 bitową liczbę całkowitą
int16_t - 16-bitowa liczba całkowita
int32_t - 32-bitowa liczba całkowita
uint8_t - 8 nieco liczba całkowita bez znaku
uint16_t - 16-bitowa liczba całkowita bez znaku
uint32_t - 32-bitowa liczba całkowita bez znaku

Niedawno zagnieżdżona muza (numer 177, a nie na stronie internetowej) wprowadziła mnie w przekonanie, że przydatne jest posiadanie pewnych specyficznych dla wydajności typów. This standard sugeruje posiadanie typedefs wskazujących, że chcesz najszybszego typu o minimalnym rozmiarze.

Na przykład, można zadeklarować zmiennej za pomocą int_fast16_t, ale w rzeczywistości być realizowana jako int32_t na 32-bitowy procesor, lub int64_t na 64-bitowy procesor, jak te byłyby najszybsze rodzaje co najmniej 16 bitów na na tych platformach. Na 8-bitowym procesorze będą to bity int16_t, aby spełnić wymóg minimalnej wielkości.

Nigdy wcześniej nie widziałem tego zużycia przed Chciałem wiedzieć

  • Widzieliście to w żadnych projektów, wbudowany lub w inny sposób?
  • Jakiekolwiek możliwe powody, aby uniknąć tego rodzaju optymalizacji w typedefs?

Odpowiedz

4

Na przykład, można zadeklarować zmienną użyciu int_fast16_t, ale będzie faktycznie realizowany jako int32_t z procesorem 32-bitowym lub int64_t na procesorze 64 bit jak byłby najszybszy typy co najmniej 16 bitów na tych platformach

Po to jest int, prawda? Czy w najbliższym czasie napotkasz 8-bitowy procesor, gdzie to nie wystarczy?

Ile unikatowych typów danych jest w stanie pamiętasz?

Czy zapewnia ona tak wiele dodatkowych korzyści, że warto skutecznie podwajać liczbę typów do rozważenia za każdym razem, gdy tworzę prostą zmienną całkowitą?

Trudno mi sobie nawet wyobrazić, że można go konsekwentnie używać.

Ktoś napisze funkcję, która zwraca int16fast_t, a następnie ktoś inny przyjdzie i zapisze tę zmienną w int16_t.

Co oznacza, że ​​w mało znanym przypadku, w którym warianty fast są rzeczywiście korzystne, może to zmienić zachowanie kodu. Może nawet powodować błędy kompilatora lub ostrzeżenia.

+0

+1 dla problemu zwrotu funkcji. Kompilator narzekałby na różne typy, jeśli są one wewnętrznie różnej wielkości po rozwiązaniu, ale nadal jest to istotne. Cały czas używam 8-bitowych procesorów w pracy osadzonej, a problemy z typedef są koszmarem (twórcy aplikacji przyjmują, że int ma 32 bity). –

+0

Tak, zdecydowanie użyj czegoś takiego, jak int32_t, jeśli potrzebujesz typu danych o szerokości 32 bitów. Przyjmowanie założenia o ogólnym rodzaju int jest źle złe. :) Po prostu mówię, że podział na typedefs na int32 i int32fast wygląda na to, że dodadzą trochę więcej niż dodatkowe zamieszanie. – jalf

0

Nie jestem zbyt wielkim fanem tego typu rzeczy.

Widziałem to już wiele razy (w rzeczywistości mamy nawet te typedefs w moim obecnym miejscu zatrudnienia) ... W większości wątpię w ich prawdziwą użyteczność ... To uderza mnie jako zmianę dla zmiany sake ... (i tak, wiem, że rozmiary niektórych wbudowanych modułów mogą się różnić) ...

3

Głównym powodem, dla którego uniknęłbym tego typu, jest to, że pozwala on typowi kłamać użytkownikowi. Weź int16_t vs int_fast16_t. Obie nazwy typów kodują rozmiar wartości w nazwie. Nie jest to rzadka praktyka w języku C/C++. Osobiście używam typedefs o określonej wielkości, aby uniknąć zamieszania dla mnie i innych osób czytających mój kod. Znaczna część naszego kodu musi działać na platformach 32- i 64-bitowych, a wiele osób nie zna różnych reguł skalowania między platformami. Typy takie jak int32_t eliminują niejednoznaczność.

Gdybym nie przeczytał czwartego akapitu twojego pytania, a zamiast tego zobaczył nazwę typu, zakładałbym, że był to jakiś specyficzny dla scenariusza sposób uzyskania 16-bitowej wartości. I oczywiście byłbym w błędzie :(Dla mnie byłoby to naruszeniem zasady programowania "nie dziwić ludzi"

Być może gdyby miał inny wyróżniający czasownik, literę, akronim w nazwie, byłoby to mniej prawdopodobne dezorientować użytkowników. Może int_fast16min_t?

+0

standard określa te wartości ... większość programistów będzie wiedziała, co oznaczają. – rmeador

+0

@rmeador, nie zgadzam się. Wiedzieliby o tym tylko programiści znający ten standard, a liczba programistów, którzy są prawie na pewno, jest o wiele mniejsza niż połowa. Z drugiej strony znajomość normy nie jest wymagana, aby zrozumieć int32_t i tym podobne. – JaredPar

+2

Wartości specyficzne dla rozmiaru są potencjalnie nieskuteczne. Istnieje zapotrzebowanie na coś w stylu "najszybszego integralnego typu danych co najmniej 16 bitów", co jest starą definicją "int". –

0

Zwykle używam size_t, to jest najszybszy rozmiar adresu, tradycja, którą podjąłem w osadzaniu. I nigdy nie powodowało żadnych problemów ani nieporozumień w kręgach osadzonych, ale w rzeczywistości zaczęło powodować problemy, gdy zacząłem pracować na systemach 64-bitowych.

+0

oof! To smaguje niebezpieczeństwo ... Co więcej, czy zawsze jest najszybszy? W architekturach segmentowych rozmiar_t może być większy niż magistrala danych, wymagający dwóch odczytów na każde minimum ... –

+0

Jakie problemy spowodowało to? Fakt, że był większy niż (zazwyczaj 32-bitowy) int?Przekształciłem wiele int do size_ts w konwersji na 64-bitowe i nie miałem z nimi problemów. –

+0

Głównie powodowane problemy z kodem serializacyjnym, nic z kilku dni naprawiania i testowania nie mogły rozwiązać, ale było to dodatkowe zadanie i wymagało śledzenia wielu zmiennych. –

2

Kiedy patrzę na int_fast16_t i nie jestem pewien co do natywnej szerokości procesora, w którym będzie działać, może to skomplikować, na przykład operator ~.

int_fast16_t i = 10; 
int_16_t j = 10; 

if (~i != ~j) { 
    // scary !!! 
} 

jakoś chciałbym celowo użyciu 32 bitów lub 64 bitów na podstawie szerokość natywnego procesora.