C _ jak rozepsat ?__ádek

Jan Waclawek konfera na efton.sk
Neděle Duben 28 12:09:03 CEST 2013


> > C99, 6.3.2.3#7
> > A pointer to an object or incomplete type may be converted to a pointer to
> > a different
> > object or incomplete type. If the resulting pointer is not correctly
> > aligned for the
> > pointed-to type, the behavior is undefined.

> >> Nejsem si jist jestli to platí i pro C90. 

Neviem, nebudem skumat, ale s najvacsou pravdepodobnostou ano. Mam tu K&R (slovensky preklad z 1989, Alfa), a v kapitole 14.4 sa pise defacto to iste ako v horeuvedenom odkaze na C99:
"Smernik na urcity typ je mozne konvertovat na smernik na iny typ. Ak sa vsak vysledny smernik odvolava na objekt, ktory nie je v pamati vhodne zarovnany, moze jeho pouzivanie sposobovat chyby adresovania."

> >>Protože to podle mě souvisí se
> >> strict aliasing vlastností C a to je specifikováno až od C99.

Suvisiet to  suvisi, ale je to vlastne silnejsia poziadavka. Strict aliasing su pravidla, za ktorych sa explicitne dovoluje pristup k premennej ako premennej ineho typu, ak sa dodrzia urcite (pomerne prisne) pravidla (C99, 6.5#7 plus suvisiaci footnote). 

> >> Možná je
> >> to důvod proč to bylo definováno, ale to je ode mě čirá spekulace.

Nie; dovodom je jednoducho to, ze sa so smernikmi nema narabat mirnix dirnix.

> >> V tom případě by u GCC mohla pomoci volba -fstrict-aliasing

Urcite nie, presne naopak, vid dokumentaciu gcc.
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fstrict_002daliasing-890
Pouzitim -fstrict-aliasing *programator* slubuje prekladacu, ze bude zachovavat pravidla strict aliasingu, co umoznuje prekladacu pouzivat urcite optimalizacie (napr. ak na objekt existuje nie strict-aliased smernik (napr. sa smernik na ne-char premennu pretypoval/priradil do smernika na char), pri -fstrict-aliasing sa neberie do uvahy, ze cez takyto smernik sa mohol zmenit obsah danej premennej, t.j. sa premenna poklada za nezmenenu). Inaksie povedane, -fno-strict-aliasing dovoluje pomerne korektne prekladat programy, ktore nezodpovedaju norme v bode o strict aliasingu.

Existuju nejake atributy co sa tyka zarovnania (align), ale uprimne povedane netusim, ci sa daju aplikovat na ciel smernika (smernikoveho typu), a ani to nemienim skumat. Viem si tiez predstavit, ze sa spravanie gcc v tomto smere da ovplyvnit prepinacmi, ktore ovplyvnuju sposob zarovnavania structov, lebo to tiez suvisi s touto problematikou (type punning, pristupovanie k tej istej oblasti pamate ako k premennym rozneho typu),  ale ani to nemienim skumat (mimochodom som si uz s tymito vecami uzil a dakujem, radsej budem stat na strane istoty, vid na konci).

> Ja zas netusil, ze u CM3,4 jsou na to specialni instrukce, 

Nie su na to (na pristup nezarovnanych halfword/word) specialne instrukcie, su to tie iste ldr atd. ako v ostatnych ARMoch. Pointa je v medzikuse medzi jadrom a externymi zbernicami, ktory "je ochotny" tie nezarovnane pristupy vykonat vo viacerych cykloch a spravne tie nezarovnane wordy/halfwordy rozlozit/zlozit.


> > Nepomůže. Nicméně je to tedy v zásadě vlastnost CM0

Nie je to nijako ARM/CM0 specificka vlastnost; naopak. Viac-nez-8-bitove procesory maju odjakziva tendenciu mat so zarovnanym/nezarovnanym pristupom (plus s endianitou) nejake specifika. V principe su mozne styri pristupy:
- nezarovnane pristupy sa spravaju uplne identicky ako zarovnane (to je asi len v pripade 8-bitovych externych zbernic)
- nezarovnane pristupy funguju, ale trvaju dlhsie ("niekto" ich rozklada/sklada)
- pri nezarovnanom pristupe sa zapise/cita nieco prekvapive (typicky ak sa jednoducho zahadzuju spodne bity adresy, t.j. ak sa zapisuje na adresu 1 PQRS a ocakava sa [1]=P, [2]=Q, [3]=R, [4]=S, tak sa v skutocnosti zapise bud [0]=P, [1]=Q, [2]=R, [3]=S alebo niekde aj [0]=S, [1]=P, [2]=Q, [3]=R; pri citani obdobne)
- pri nezarovnanom pristupe nastane chyba (trap). Toto mal uz aj PDP11 (skalni Cckari samozrejme vedia, preco spominam prave PDP-11 :-) )

> > To je dobrá informace. Studovat specifikace to je pro mě projev krajního zoufalství.

Studovat specifikacie a snazit sa pochopit fungovanie veci okolo nas je IMO prospesna vec z viacerych dovodov; ale ak sa Vam to nechce, tak jednoducho nepouzivajte "skutocne C", t.j. rozne "skratky" a "finty". Konkretne vo Vasom pripade ak chcete zlozit zo 4 bytov lubovolne umiestnenych v poli jeden 32-bitovy word, nuz to tak aj zapiste, pomocou nasobeni (posuvov) a scitovani. Toto je (pri zachovani pravidiel aritmetiky v C, co tiez nie je trivialne :-( ) bezpecne a prenositelne. Ak sa Vam to zda roztahane, spravte si na to makro. Ak mate obavy, ze je to neefektivne, tak zabudnite na C a pouzivajte assembler.

wek


Další informace o konferenci Hw-list