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