Typy v C++

Michal Gregor a2x1nptda8 na email.cz
Sobota Leden 15 10:40:31 CET 2022


Tak MISRA neni zbytecna. Ono to ignorrovani warningu se dost vymsti:

uint16_t Teplota;
uint8_t TeplotaZobrazena;
TeplotaZobrazena = Teplota;
Prekladac tam samozrejme dal warning, ale vsichni na to kaslali. A pak 
se hledala chyba asi dva dny.
Krome toho TeplotaZobrazena je pouze Fahrenheita ale Teplota muze byt i 
v celsiech.

Nebo tohle
if (zapis)
	Log(teplota);
teplota = teplota + 23;

Dalsich par dni zabitych, kvuli lenosti. Log neni funkce, ale makro, 
ktere funguje pouze v debug verzi. Takze se radek teplota = teplota + 
23; ignoroval.

Spravne to ma byt:
if (zapis)
{
	DEBUG_LOG(teplota);
}



Michal Gregor


Dne 15.01.2022 v 10:20 Jan Waclawek napsal(a):
>> No a já mám nepìkné pocity z celého C, tím se øídit nemù¾u :)
> 
> Tak su dve cesty: bud budete ten pocit ignorovat, ako to robi 99.9%
> normalnych programatorov, alebo stravite strasne vela casu skumanim
> nechutnych podrobnosti, vratane citania (ci dokonca pisania) "skutocnej
> dokumentacie" (t.j. zdrojovych textov prekladacov a kniznic) a
> normativnych materialov... a toto moze robit iba blazon... ;-)
> 
> Warningy, ktore do gcc pribudli niekedy po roku 2010, nevychadzaju z
> poziadaviek jazyka/normy, ale skor z predstavy, ze existuju jednoduche
> pravidla, ktorych dodrziavanie znizuje chybovost programov. Je to ta ista
> predstava ktora motivuje aj predpisy typu MISRA; bohuzial je to zalozene
> len na pocitoch autorov, bez akychkolvek realnych dokazov. Ale to je na
> pivnu debatu.
> 
> Konkretne tu gcc priamo napovie, cim bol dany warning zapnuty
>> int*'} [-Wformat=]
> a tento prepinac je popisany samozrejme v manuali
> https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wformat
> (treba zarolovat dva riadky nahor)
> cize sa jedna o warning specificky pre rodinu printf()/scanf() prip.
> kniznicne funkcie specialne oznacene v zdrojovom texte danej kniznice.
> 
> V dalsom budem hovorit len o C, pretoze C++ nepoznam, a C++ *je* iny jazyk
> ako C (v tomto kontexte by mohlo byt zaujimave skusit prelozit
> inkriminovany riadok ako C).
> 
> Napriek tomu, ze ich interna reprezentacia je identicka, 'unsigned int' je
> *iny typ* nez 'unsigned long int', a uint32_t je typedef-ovany (co v C ma
> len slaby vyznam, znamena to len premenovanie) v tomto konkretnom
> prekladacom prostredi specificky ako unsigned long int. V inych
> prekladacich prostrediach to moze byt inak (dokonca aj keby islo o gcc pre
> Cortex-M, kedze tento typedef je dany v <stdint.h>, t.j. v standardnej
> kniznici a nie v kompilatore). Ale v dalsom berme, ze uint32_t je rovny
> unsigned long int.
> 
> Pri volani funkcie v C sa na parametroch ako prve urobia implicitne
> konverzie. Takze ak mame funkciu, ktora vyzaduje smernik na unsigned int,
> a dame mu smernik na uint32_t, dojde k implicitnej konverzie medzi tymito
> smernikmi. Su to smerniky na rozne typy, a na takuto konverziu podla
> 6.3.2.3 nie su kladene ine podmienky ako spravne zarovnanie v pamati, a ak
> je interna reprezentacia bazovych typov v oboch pripadoch rovnaka, tak aj
> dereferencovanie konvertovaneho smernika dopadne ocakavanym sposobom. Ak
> by tie interne reprezentacie boli odlisne, prekladac sice nemusi urobit
> nic zle, ale tam je warning opravneny.
> 
> Lenze u printf()/scanf() sa situacia komplikuje tym, ze sa jedna o funkcie
> s variabilnymi parametrami, t.j. v prototype je za formatovacim retazcom
> '...'. Kedze variabilna cast parametrov sa vyhodnocuje az pri behu
> programu, prekladac vo vseobecnosti nema sancu ich skontrolovat. Kedze sa
> vsak jedna o standardardnu kniznicu, gcc ma rozsirenie, ktorym si
> zinterpretuje formatovaci retazec rovnako ako by ho mala interpretovat
> samotna printf()/scanf() funkcia, a na zaklade toho tie parametre
> kontroluje - toto rozsirenie je riadene prave tym -Wformat-om. Tato
> kontrola je vsak uz ina, nez ta, ktoru robi prekladac pri kontrole
> parametrov "normalnych" funkcii, proste ma svoje pravidla, a tie dva
> smerniky sa vyhodnotia ako odlisne a vypise sa chyba. Ako vravim, warningy
> su viacmenej vecou individualnych rozhodnuti silno argumentujucich
> jedincov, a tato "zvysena prisnost" je rozhodnutie toho, kto to rozsirenie
> pisal. Mozno na to existuju nejake dobre argumenty, ja neviem.
> 
> Takze ako z toho von:
> 
> - vypnut tu kontrolu, tj. pouzit -Wno-format, ci uz lokalne pre danu
> funkciu (s pouzitim prislusnej #pragma, nechce sa mi to hladat) alebo v
> prikazovom riadku pre cely subor
> 
> - pouzit modifikovany specifikator (ano! :-)  %lX ako to navrhuje
> prekladac, co vyuziva fakt ze v tomto prekladacom prostredi uint32_t ==
> unsigned long int (t.j. je to neprenosne)
> 
> - pouzit specifikator PRIu32 specificky pre uint32_t podla <inttypes.h>
> printf("%" PRIu32 "\n",a); - toto je prenosne ale esteticky nepekne...
> 
> - explicitne pretypovat na typ, ktory chcem vytlacit - kedze podla normy
> specifikator X je specificky pre unsigned int, tak printf("%X\n",(unsigned
> int)a);
> 
> - nepouzit printf()/scanf(), lebo [slovo do bitky] printf()/scanf() do mcu
> nepatria [/slovo do bitky] - ako Jindroush pisal, v tomto pripade je
> vhodnejsie pouzit strtoul()
> 
> wek
> 
> 
> 
> ----- Original Message ---------------
> 
> Subject: Re: Typy v C++
>     From: "Pavel Kutina" <hw na prelude.cz>
>     Date: Fri, 14 Jan 2022 17:32:52 +0100
>       To: "HW-news" <hw-list na list.hw.cz>
> 
> Mo¾ná by to lep¹í bylo - tedy nebýt toho, ¾e ho neznám, a ¾e kolega pøi¹el
> s
> tím ¾e "to se øe¹ilo támhle v XXXX.c, tak to napi¹ podle toho."
> 
> No a já mám nepìkné pocity z celého C, tím se øídit nemù¾u :)
> 
> Pavel Kutina
> 
> 
> 
> ----- Original Message -----
> From: "Jindroush" <jindroush na seznam.cz>
> To: "HW-news" <hw-list na list.hw.cz>
> Sent: Friday, January 14, 2022 5:19 PM
> Subject: Re: Typy v C++
> 
> 
> Ale ten komplikator tam napovida, ze misto %X pouzit treba %lX a je
> vymalovano.
> Ostatne, nebylo by lepsi pouzit strtoul, ja mam z toho sscanfu vzdycky
> takovy nepekny pocity?
> J.
> 
> On 14.01.2022 17:12, Pavel Kutina wrote:
>> U¾ jsem to dohledal:
>>
>> ////unsigned int cnt = 0; // tohle je bez výhrad
>> uint32_t cnt = 0;
>> sscanf(pData, "%X", &cnt);
>>
>> ../src/receive.cpp:117:19: warning: format '%X' expects argument of type
>> 'unsigned int*', but argument 3 has type 'uint32_t*' {aka 'long unsigned
>> int*'} [-Wformat=]
>> 117 | sscanf(pData, "%X", &cnt);
>> | ~^ ~~~~
>> | | |
>> | | uint32_t* {aka long unsigned int*}
>> | unsigned int*
>> | %lX
>>
>>
>> Pokud to deklaruju jako 16bit:
>>
>> uint16_t cnt = 0;
>> sscanf(pData, "%X", &cnt);
>>
>> ../src/receive.cpp:117:19: warning: format '%X' expects argument of type
>> 'unsigned int*', but argument 3 has type 'uint16_t*' {aka 'short unsigned
>> int*'} [-Wformat=]
>> 117 | sscanf(pData, "%X", &cnt);
>> | ~^ ~~~~
>> | | |
>> | | uint16_t* {aka short unsigned int*}
>> | unsigned int*
>> | %hX
>>
>>
>> Jinak to je pro STM32L471, máme je¹tì pár kouskù "z pøedváleèných zásob".
>>
>> Pavel Kutina
>>
>>
>> ----- Original Message ----- From: "Tomá¹ Hamouz"
>> <konfery.tomas.hamouz na seznam.cz>
>> To: "HW-news" <hw-list na list.hw.cz>
>> Sent: Friday, January 14, 2022 5:01 PM
>> Subject: Re: Typy v C++
>>
>>
>> A nebyl to pointer na unsigned? Pokud bys tam strèil *uint16_t tak by
>> do¹lo k pøepsání dat.
>>
>> Jinak délka int a unsigned int jsou implementaènì závislé, musí jen
>> platit ¾e
>>
>> sizeof(short) <= sizeof(int) <= sizeof(long)
>>
>> V¹imni si ¾e short mù¾e být stejnì dlouhý jako long a bude to podle
>> normy ;-)
>>
>> Tomá¹
>>
>>
>>
>>> No nezbývá, ne¾ se nauèit dávat si na to bacha :(
>>
>>> A ten rozdíl mezi unsigned int a uint16_t (uint8_t, uint32_t atd.) taky
>>> nìkdo umíte vysvìtlit? Vyøval mne sscanf a tam jsem tio vzdal a
>>> pøíslu¹nou
>>> promìnnou deklaroval jako unsigned int (bohu¾el pøslu¹ná èást kódu pro¹la
>>> demolicí, teï to nedoká¾u zrekonstruovat).
>>
>>> Jinak jaké je doporu¹ení? Pro mne je deklarace pøes ty pøetypované _t
>>> pøehlednìj¹í, ale nejspí¹ to nemusí být v¾dycky toté¾.
>>
>>> Pavel Kutina
>>
>>
>>> ----- Original Message ----- From: "Jindroush" <jindroush na seznam.cz>
>>> To: "HW-news" <hw-list na list.hw.cz>
>>> Sent: Friday, January 14, 2022 4:30 PM
>>> Subject: Re: Typy v C++
>>
>>
>>> odpoved uz dosla s vysvetlenim... Jinak jsem to nacpal do
>>> https://cppinsights.io/
>>
>>> a zaskrtl, at ukaze implicitni konverze, tam je to videt na vlastni voko
>>> if((static_cast<unsigned int>(static_cast<int>(LastCounter) + 1)) == cnt)
>>> {
>>
>>> On 14.01.2022 16:13, Pavel Kutina wrote:
>>>> Zdravím,
>>>>
>>>> opìt nìco nechápu, mù¾ete mne po¹touchnout?
>>>>
>>>> Pí¹u FW v STM Cube, mám deklarované dvì promìnné:
>>>>
>>>> unsigned int cnt = 0;
>>>> uint16_t LastCounter = 0;
>>>>
>>>> pøi porovnání v:
>>>>
>>>> if (LastCounter+1 == cnt)
>>>>
>>>> mi to pí¹e warning:
>>>> ../src/receive.cpp:129:22: warning: comparison of integer expressions of
>>>> different signedness: 'int' and 'unsigned int' [-Wsign-compare]
>>>> 129 | if ( (LastCounter+1) == cnt)
>>>> | ~~~~~~~~~~~~~~^~~~~~
>>>>
>>>> Chápu dobøe, ¾e unsigned int a uint16_t nejsou znaménkovì kompatibilní
>>>> typy? Proè ne?
>>>>
>>>> Na nìco podbného jsem narazil pøed chvílí u sscanf, kde se mi to zase
>>>> vztekalo pri pou¾ití uint16_t (jsem tam mìl) místo unsigned int (který
>>>> to
>>>> chtìlo).
>>>>
>>>> Popravdì, asi 90% èasu tohoto projektu trávím rovnáním datových typù,
>>>> hodne v tom plavu :(
>>>>
>>>> Díky.
>>>>
>>>> Pavel Kutina
>>>>
>>>> _______________________________________________
>>>> HW-list mailing list - sponsored by www.HW.cz
>>>> Hw-list na list.hw.cz
>>>> http://list.hw.cz/mailman/listinfo/hw-list
>>
>>
>> _______________________________________________
>> HW-list mailing list - sponsored by www.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>> _______________________________________________
>> HW-list mailing list - sponsored by www.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
> 
> 

-- 
Tato zpráva byla zkontrolována na viry programem Avast Antivirus.
https://www.avast.com/antivirus



Další informace o konferenci Hw-list