GCC - implicitní číselný datový typ

Ondřej Staněk ostan89 na gmail.com
Středa Březen 18 11:52:19 CET 2015


Zdravím konferenci,
vrtá mi hlavou jakým způsobem lze nastavit implicitní číselný datový typ 
pro překladač GCC. Vysvětlím na příkladě:

#include <stdint.h>

static uint32_t dirtyFlags = 0;

static void setDirtyFlag(const uint8_t registerNumber) {
     dirtyFlags |= 1<<registerNumber;
}

Parametr funkce je číslo registru, od 0 do 31. Očekává se, že funkce 
nastaví patřičný bit v proměnné dirtyFlags.

Programátor ale zapomněl přetypovat jedničku na pravé straně na 
uint32_t, takže pokud kód kompilujeme pro 8bit AVR (avr-gcc), nebude 
funkce správně fungovat pro argumenty větší jak 15. To je dáno tím, že 
překladač (avr-gcc) jedničku implicitně přetypuje na 16bit integer 
(domněnka), výraz na pravé straně přeteče a v důsledku se dirtyFlags 
nezmění.

Stejný kód ale funguje naprosto v pořádku pokud je kompilován pro PC 
(gcc). Tam je totiž jednička implicitně převedena na 32bit integer (nebo 
větší).

No a konečně se dostáváme k jádru věci. Potřebuji zařídit, aby tento 
kousek kódu vykazoval stejně _chybné_ chování i pokud je 
kompilován/spouštěn na PC.
Otázka zní - jak nastavit parametry překladače GCC, aby se i na PC 
projevila stejná chyba jako na 8bit AVR? Tedy jak vynutit, aby na 
64bitovém stroji překladač prováděl implicitní konverze konstant na 
16bit integer?

Možná to může vypadat trochu obskurně, proto vysvětlím i motivaci, proč 
chci něčeho takové dosáhnout:

Mám multiplatformní C kód, který finálně poběží na 8bitové platformě 
(AVR). Kód je pokrytý automatickými testy (unit tests). Automatické 
testování probíhá na PC, kvůli rychlosti a snadnému debugování. Proto se 
kompiluje jiným překladačem (gcc) pro testování a jiným překladačem 
(avr-gcc) pro cílovou platformu. Emulátor není možné při testech použít, 
kód musí běžet nativně na PC (kvůli testovacímu frameworku a vazbám na 
integrační testy).
Snažím se eliminovat rozdílné nastavení/vlastnosti překladačů tak, aby 
byly výsledky co možná nejpodobnější. No a tohle implicitní přetypování 
je velmi kritická věc, proto chci přinutit GCC aby se chovalo stejně 
jako avr-gcc pro 8bit.

Googlil jsem a našel jsem člověka co si položil podobnou otázku, zdá se 
že ale nebyl zcela pochopen:
https://gcc.gnu.org/ml/gcc-help/2004-08/msg00178.html

Lze vůbec nastavit šířku implicitního číselného typu v gcc?
Má tato metoda testování potenciálně nějaké další problémy? Z principu 
to nikdy nebude 1:1, ale je dobré vědět co je případně potřeba 
dotestovat ručně, na co si dát pozor atd..

Díky,
Ondra Staněk


Další informace o konferenci Hw-list