Makro v C - "text" to uint32_t

Jan Waclawek konfera na efton.sk
Úterý Listopad 7 10:01:00 CET 2017


Hm, ta hlaska je zaujimava, ale dovod je jasny: v case mozete pouzit len
tzv. integer constant expression, a to ma pomerne striktne a jasne
pravidla dane v C99 6.6#6 "...shall only have operands that are integer
constants, enumeration constants, character constants, sizeof expressions
whose results are integer constants, and floating constants that are the
immediate operands of casts." Zabudnite na retazce.

Nasledujuci 6.6#7 zacina zaujimavou vetou: "More latitude is permitted for
constant expressions in initializers." ale aj tak sa v #8 jasne pise "Cast
operators in an arithmetic constant expression shall only convert
arithmetic types to arithmetic types, except as part of an operand to a
sizeof operator whose result is an integer constant."; a aj ked sa v 10
pise "An implementation may accept other forms of constant expressions.",
pretypovanie, co je samo osebe operacia s nedefinovanym vysledkom,
notabene na string literal, medzi ne s najvacsou pravdepodobnostou patrit
nebude. V manuale gcc som v C implementation zmienku o 6.6 nenasiel.

Preprocesor v tejto suvislosti nemusite vobec spominat, ten o stringoch vie
len to ze to je nieco uzavrete v uvodzovkach, urcite s tym neurobi nic
(preprocesor je textova zalezitost a nerobi ziadnu aritmetiku atd.)

Mozete si napisat vlastny preprocesor ktory Vam tie stringy skonvertuje
este pred pustenim "bezneho" prekladu.

Dalsia moznost (mozno neefektivna, ale mozno to je akceptovatelna
neefektivita v mene citatelnosti) je si tie stringy ulozit do pola a
napisat konverznu funkciu ktora najde index pre dany string (prip. pouzit
kniznicnu funkciu bsearch()).

Tretia, mozno pre Vas najzaujimavejsia moznost je vyuzit tzv.
multicharacter character constants, t.j. to, ze 'abcd' je legalna integer
konstanta; pre gcc funguje "ocakavnym sposobom" zdokumentovanym v
https://gcc.gnu.org/onlinedocs/cpp/Implementation-defined-behavior.html#Implementation-defined-behavior
. Nepozivam to. Ak tomu dobre rozumiem, pre porovnanie so stringami si asi
budete muset napisat konverziu po znakoch, lebo ten popisany postup
konverzie multicharacter character constant ma charakter "big endian"
(alebo pouzit niektoru formu type punning a potom bytewise swap, co v ARMe
je jedna instrukcia). Kedze je to v implementation-defined, tak je to
samozrejme neprenositelne a viem si predstavit, ze napr. prepinace
ovplyvnujuce sirku typu char (-fexec-charset ?) s tym tiez mozu urobit
sarapatu.

wek


----- Original Message ---------------

Subject: Re: Makro v C - "text" to uint32_t
   From: "Pavel Hudecek" <edizon at seznam.cz>
   Date: Tue, 7 Nov 2017 01:20:05 +0100
     To: "HW-news" <hw-list at list.hw.cz>

>Pro jistotu jsem zkusil *, ale bez úspìchu:
>
>#define STRtoINT(s) *(uint32_t *)(s)
>
>Ještì jsem to zkoušel rùznì ozávorkovat, ale výsledek vždy stejný:
>error: label at end of compound statement
>
>(MCUXpresso IDE v10.0.2 [Build 411] [2017-07-11])
>
>PH
>
>-----Pùvodní zpráva----- 
>From: Pavel Hudecek
>uint32 byl jen souèást pøíkladu použití vzniklého èísla
>
>Obecnì mi jde o to, aby výsledkem bylo jedno èíslo, asi jako kdybych tam
>napsal 12345. Použití * se v tomto pøípadì trochu bojím, asi nìkdy narazí na
>chybu zarovnání, když ten text nebude ležet na správném místì. Radši bych
>donutil preprocesor, aby z toho udìlal èíslo.
>
>Praktických využití je v daném programu více, napø. i toto:
>
>switch (N) {
>case MAKRO("abc"): ...
>case MAKRO("xyz"): ...
>}
>
>-----Pùvodní zpráva----- 
>From: Jaroslav Buchta
>A proc zrovna uint32_t?
>Pokud chcete prave 4 znaky na 32b cislo tak nejak takto
>
>uint32_t x = *(uint32_t *)"abcd";
>
>kdyz makro, tak
>#define MAKRO(s)  *(uint32_t *)(s)
>kde s bude ten retezec.
>
>Bezneji se ale pracuje s jednotlivymi znaky, to, co je mezi uvozovkami
>ma vlastnosti konstantniho pole znaku a da se k tomu pristupovat jako k
>poli cisel
>char *s = "abcdefgh...";
>uint8_t a0 = (uint8_t)s[0];
>...
>Z toho si pak taky muzete vyskladat libovolne hodnoty.
>
>Dne 06.11.2017 v 21:13 Pavel Hudecek napsal(a):
>> z "ble" by mohlo být napø. 'b' + 'l'<<8 + 'e'<<16 + 0 nebo ty bajty v 
>> opaèném poøadí, je to vlastnì jedno.
>>
>> Tzn. jde mi o to, jak se v makru dostat k èíslùm reprezentujícím 
>> jednotlivé znaky textu. Zbytek si už pak vyøeším sám.
>>
>> PH
>>
>> -----Pùvodní zpráva----- From: Jaroslav Buchta
>>
>> A co si predstavujete, ze v tom x ma pak byt? Muzete napsat priklad ve
>> smyslu "xxxx" -> 0x.... ?
>>
>> Dne 06.11.2017 v 20:51 Pavel Hudecek napsal(a):
>>> potøeboval bych makro, se kterým by šla konstrukce typu:
>>>
>>> uint32_t    x = MAKRO("ble");
>>>
>>> jen vùbec nevím, jak v makru pracovat s textem (const char) a ani nevím 
>>> jak to hledat. 
>
>_______________________________________________
>HW-list mailing list  -  sponsored by www.HW.cz
>Hw-list at list.hw.cz
>http://list.hw.cz/mailman/listinfo/hw-list



Další informace o konferenci Hw-list