pole bitového pole v C

Jan Waclawek konfera na efton.sk
Sobota Leden 12 12:08:08 CET 2013


> > SPIout_bity. PoleBitu[2]=1; //nastav 3 bit v 23bitovém poli.

Kratka odpoved je, ze to nejde a musite si najst ine, "manualne" riesenie (napr. pouzivat shifty a masky).

Teraz ta dlha odpoved :-):

> To IMHO nejde.

Ano, to nejde; dovodov je viacero a vsetky su principialne. Jeden je, ze bitove pole ma predpisanu syntax a tam ziadne miesto pre [] nie je; druha je, ze bitove pole nie je "objekt", t.j. nema adresu (neda sa na neho aplikovat operator &); tretia je, ze v C polia neexistuju, a ta syntakticka finta ze identifikator z deklaracie pola sa interpretuje ako smernik (a nasledne pouzitie a[b] sa priamo konvertuje na *(a + b) kvoli predchadzajucej vlastnosti nemoze fungovat.

Mimochodom, toto je uvedene aj priamo v standarde, v C99 v poznamke 106 k 6.7.2.1#8.

> Ani nevim, jestli je normou dane poradi bitu v tech

Nie je, a toto je znova priamo uvedene v 6.7.2.1#10.
Naviac, podla toho isteho odstavca, sa moze prekladac volne rozhodnut, ci sa bude jednotlive bitove polia snazit pchat jeden za druhy, alebo ich rozhadze kazdy do jedneho byte ci dokonca vacsieho kusu pamate.
 
> promennych uchar (a spis tusim, ze to je standardne narvane do typu int)

Ako som hore uviedol, prekladac sa moze sam rozhodnut, ako bitove polie ulozi, a to bez ohladu na deklarovany typ. 6.7.2.1 v principe povoluje akykolvek typ. Dokonca jednym z problematickych bodov je aj benevolentnost normy s ohladom na znamienkovost bitoveho pola, ak je predpisanym typom int bez explicitneho signed alebo unsigned - vid napr. "nadherny" priklad 3 v 6.7.7#6...

Bohuzial, aj ked zakladna uloha normy ako takej je dosiahnut jednotne spravanie prekladacov a tym co najvacsiu prenositelnost; postoj normovacej komisie v podstate od zaciatku je ten, ze zmeny v norme maju zachovavat exitujuce spravanie co najvacsieho poctu prekladacov (ktore si vzdy robia nejake vlastne rozsirenia co su vlastne zakladnym podnetom pre rozsirovanie normy), a preto sa castokrat zrodili a stale rodia kompromisy ktore v podstate skodia prenositelnosti...

> Ja uz jsem natolik zdegenerovany, ze pro typ BOOL pouzivam klasicky po 
> windowsovsku: typedef unsigned char BOOL;  ;-)

C99 definuje _Bool ako jeden zo zakladnych typov (mimochodom je to celociselny typ). Dalej standardna hlavicka <stdbool.h> obsahuje makro bool pre tento isty ucel (7.16#2); pokial viem, bool je zakladny typ v C++. Ak len neplanujete prekladat Vas program v buducnosti nejakym obskurnym prekladacom, nevidim prilis dovod preco sa nedrzat tychto standardnych typov.

Zdalo by sa, ze ak existuje typ, ktory je urceny na ulozenie jednobitovej hodnoty, tak prekladace (aspon tie pre 8-bitove mcu/mpu) budu mat tendenciu ich ukladat efektivne do jedneho bitu pamate, Bohuzial, nepoznam prekladac, co by to tak robil; naviac pred par rokmi sme v ramci SDCC diskutovali, ci to je vobec mozne, a zda sa, ze norma tomu - mozno nechtiac, mozno nasledkom implementacie niekolkych nesuvisiacich poziadaviek - defacto brani kombinaciou niekolkych formalnych poziadaviek.

Spomenuty typ sbit pouzivany prekladacmi pre '51 vychadza, tak ako pan kolega Andel povedal, z faktu, ze '51 ma implementovanych 128 bitov bitovo adresovatelnej pamati (to je 16 byte na bytovych adresach 20h-2fh). Na tejto pamati sa dokonca daju robit aj urcite logicke operacie. Premenne typu sbit takto umoznuju vyuzivat tieto instrukcie priamo programom v C. Na druhej strane vsak vsetky instrukcie pracujuce s touto pamatou maju priamu adresaciu, t.j. adresu operandu je nutne poznat v case prekladu. Aj ked nie je nemozne programom toto obist (t.j. z adresy znamej len pocas behu programu vypocitat adresu bytu v ktorom je bit ulozeny a manipulovat tento byte), nema to prilis velky vyznam a bolo by to zbytocne pracne, takze to implementovane pokial viem v ziadnom prekladaci nie je; co okrem ineho znamena, ze na premenne typu sbit nie je mozne pouzit operator & a tym padom ani nie je mozne ich ukladat do pola.

wek


Další informace o konferenci Hw-list