ceckovy kviz

Pavel Hudeček edizon na seznam.cz
Úterý Září 5 10:51:01 CEST 2023


Myslím, že je lepší mít program funkční proto, že vím co dělám, ale i 
přesto v něm zbytečně nevymejšlet koniny:-)
Jestli se má zobrazit řádek textu, tak nejspíš stejně bude potřeba, aby 
někdo měl čas si ho přečíst, takže není důvod šetřit nějaké nanosekundy. 
Tzn. dal bych tam normální funkci. A ať si s ní optimizér pak udělá co chce.

PH

Dne 05.09.2023 v 8:46 Jan Waclawek napsal(a):
> Je pravda, ze to makro je v tomto pripade nerozumne, a ta funkcia je
> rozumnejsie riesenie.
>
> (Na druhej strane, ta posadnutost pravovernych C++-karov tym const...
> zhodou okolnosti v tomto konkretnom programe ten retazec konstruujem...)
>
> Ale neviem, ako by mi to malo dojst. Aj som to skusil, gcc s -Wall a
> -Wpedantic nic nevyhlasil. A ani nema dovod. Ale ano, zakryje to problem.
>
> Ano, cely problem je v tom, ze strlen() ma navratovy typ unsigned
> (spominany size_t), a -strlen() je teda uplne rovnako unsigned (dost dlho
> som hladal v C99 kde to presne je, ze vysledok vyrazu ma ten isty typ ako
> su konvertovane typy operandov, lebo to nie je v kapitole Expressions kde
> by som to cakal, ale v kapitole 6.3.1.8 Usual arithmetic conversions).
> Inaksie povedane, ak je retazec dlhy povedzme 3, tak -strlen je u
> 32-bitoveho mcu 0xFFFFFFFD.
>
> Cize v makre to ((xx) < 0) je vzdy false a optimalizator to true vetvu
> vyhodi.
>
> Funkcia to zachrani tym, ze pri volani sa ta unsigned value skonvertuje na
> signed. To je sice, prisne vzate, implementation defined, ale u twos
> complement (co je defacto standard a od C23 bude povinne) to dopadne dobre
> :-).
>
> A teraz, co je lepsie? Mat zhodou okolnosti funkcny program nad ktorym by
> ma ani nenapadlo sa zamysliet; alebo sa na nefunkcnom programe naucit, ze
> size_t je unsigned a miesanie unsigned so signed zvykne dopadnut zle,
> takze sa tomu treba vyhybat?
>
> wek
>
>
> ----- Original Message ---------------
>
> To je jednoduché - vy pravověrní C-čkaři pouľíváte makra i tam, kde se
> to vůbec nehodí. Kdybyste pouľívali raději statické inline funkce jako
> static inline void LcdBXPrint (int xx, int yy, const char * s) {
>     LcdBPrint( (((xx) < 0) ? LCD_XMAX : 0) + (xx) * FONT_XSIZE, (yy) *
> FONT_YSIZE, s);
> }
> pak vám dojde, ľe argument xx nemůľe být unsigned (resp. size_t), pokud
> má vyhodnocen jako záporný a problém zázračně zmizí.
>
> Mrazík
>
> On 03. 09. 23 23:00, Jan Waclawek wrote:
>> Mam funkciu
>>
>>     void LcdBPrint(uint32_t x, uint32_t y, char * s);
>>
>> ktora vypise retazec na LCD s rozmermi LCD_XMAX, LCD_YMAX na poziciu x, y
>> pixelov od laveho horneho rohu.
>>
>> Vypisuje to neproporcionalnym fontom s rozmermi znaku FONT_XSIZE,
>> FONT_YSIZE.
>>
>> Z nejakych dovodov chcem vypisovat retazce zarovnane jeden za druhym; ale
>> niekedy chcem vypisovat retazce pod seba zarovnane na pravy okraj. To prve
>> vedie na volania typu:
>>
>>     LcdBPrint(doteraz_napocitane_znaky_od_laveho_okraja * FONT_XSIZE, riadok
>> * FONT_YSIZE , retazec);
>>
>> a to druhe na
>>
>>     LcdBPrint(LCD_XMAX - strlen(retazec) * FONT_XSIZE, riadok * FONT_YSIZE,
>> retazec);
>>    
>> Vravim si, takto je to dost neprehladne, a pritom sa tam to nasobenie furt
>> opakuje. A tiez, tie dve veci su navzajom dostatocne podobne. Tak co keby
>> ze si napisem makro, do ktoreho bud zadam kladne x, co znamena pocet
>> znakov od laveho okraja, alebo zaporne x, co znamena pocet znakov od
>> praveho okraja:
>>
>>     #define LcdBXPrint(xx, yy, s) LcdBPrint( (((xx) < 0) ? LCD_XMAX : 0) +
>> (xx) * FONT_XSIZE, (yy) * FONT_YSIZE, s)
>>
>> Ked pisem zlava, tak mam
>>
>>     LcdBXPrint(doteraz_napocitane_znaky_od_laveho_okraja, riadok, retazec);
>>
>> co je pekne, prehladne, a funguje. Ale ked pisem zlava, tak
>>
>>     LcdBXPrint(-sizeof(retazec), riadok, retazec);
>>
>> nefunguje.
>>
>> Preco?


Další informace o konferenci Hw-list