funkce v C - pro€ to nechod

Jan Waclawek konfera na efton.sk
Středa Prosinec 30 15:59:00 CET 2015


> [nechut voci typom zo <stdint.h>]

Na tuto temu sa da tiez dlhsie diskutovat, ale ak ta nechut vyplyva len z toho tazkopadneho zapisu, da sa riesit typedefmi, caste su zapisy typu u8, u32, i32 apod. Ale potom si treb davat pozor na to, aby sa clovek nenecha uniest a nenapisal nieco ako:

> ano, návrat z eeprom je typ byte

lebo byte nie je typ v C a tipujem ze nie je ani v C++. O ano ja chapem ze v arduine (nech to znamena cokolvek) niekde nejaky prislusny typedef ci definicia makra je, ale napriklad ja nearduinujem, takze tato informacia je napriklad pre mna nerelevantna, t.j. na jej zaklade neviem poradit... V tomto pripade je to fuk, ale chapete co tym chcem povedat.

> Výsledek má být long, jak to napsat aby u¾ ten souèin probìhl jako long?

Typ vysledku operacie je dany typmi operandov a nie typom, do ktoreho je vysledok operacie priradeny. V skutocnosti je priradenie tiez samostatnou operaciou, ktora sa vdaka nizkej precedencii priradenia vykona ako posledna, po nasobeni a scitani (a rovnako ako ine operacie, priradenie ma aj vysledok, ktory je pouzitelny v dalsich operaciach, vdaka comu sa daju priradenia "zretazovat" a = b = 5; a "vdaka" comu sa da spravit chyba typu if (a = 5)). 

Co sa tyka typov, rovnako je to aj s operatorom return - ten len vezme vysledok predchadzajucich operacii (ktore su uz vtedy ukoncene a vysledok uz maj svoj typ) a pretypuje ho na typ dany v "hlavicke" funkcie.

Pred binarnymi operaciami ako je nasobenie a scitanie sa robia "obvykle aritmeticke konverzie", ktorych ucelom je priviest operandy na "najmensi spolocny typ" - ak je medzi operandami niektory float alebo double tak na najmensi pouzitelny z nich, inak najmensi v rade int-unsigned-long-unsigned long-long long-unsigned long long.  Ciselne konstanty maju implicitny typ dany ich velkostou aj sposobom zapisu (napr. pre hexadecimalne su mierne ine pravidla).  No a tento "najmensi spolocny typ" je potom aj typom vysledku operacie. Operacie sa vykonavaju postupne po jednom, v poradi danom pravidlami precedencie a asociativity, t.j. Tu najprv vsetky tri suciny (pricom nie je stanovene, ze v akom poradi, t.j. aj tie tri vollania funkcii/metod mozu nastat v lubovolnom poradi), potom lave scitanie, prave scitanie a napokon priradenie.

Na zabranenie pretecenia v tom druhom sucine staci teda, aby jeden z operandov bol unsigned int co je v avr-gcc  uint16_t. To sa da dosiahnut bud explicitnym pretypovanim jedneho z operandov alebo aj oboch, alebo staci, ak sa za 256 napise U. 

Pretypovanim jedneho ci oboch operandov na long (alebo suffixom L za 256) sa dosiahne, ze sucin bude prevedeny znamienkovo 32-bitovo, co nie je u 8-bitoveho mcu optimalne, aj ked optimalizator nasledne moze usudit, ze vzhladom na rozsah vstupnych hodnot a na konstantu 256 staci puhe presunutie bytov. Moze, ale nemusi :-)

Mimochodom, aj to pretecenie v povodnom priklade, kedze je vysledok nedefinovane, moze dopadnut rozne - od nahodneho vysledku ("co prave bolo nahodou v registroch") cez konstantny vysledok, pad programu, koniec znameho vesmiru, az po spravny vysledok (dosiahnuty nespravnym sposobom). V tomto konkretnom pripade to posledne nie je vonkoncom nepravdepodobne, kedze to nepredstavuje vyznamnejsiu namahu oproti tej "optimalizacii", a tipujem, ze s inou verziou prekladaca alebo inymi nastaveniami by ste k tomuto mohli aj dospiet.

V prvom sucine je konstanta implicitne long, takze sucin je tiez znamienkovy long, nasledne sucty su postupne tiez long (prave operandy su vzdy konvertovane), az napokon return konvertuje celkovy vysledok na unsigned long.

Moje doporucenie je u mcu aplikacii drzat sa co najviac neznamienkovych typov, s vynimkou situacii ked ma znamienko vyznam - a tam byt co najexplicitnejsi a solidne komentovat.


Re pan kolega Mrazik: je pekne ze v jednom maile ste vysvetlili do podrobnosti dovody Vasho okuzlenia tymi ++ featurami, a jednym dychom ste hned v uvode napisali, ake matuce to pre uzivatelov moze byt... :-)

wek




Další informace o konferenci Hw-list