Re: Adresace přes pointer

Jan Waclawek konfera na efton.sk
Čtvrtek Říjen 26 13:43:48 CEST 2023


Prva vec je to co pise pan kolega Buchta, t.j. ze ten struct moze byt
"deravy". V gcc sa da predpisat, aby struktura nebola derava, pomocou
__attribute__((packed)); tipujem, ze ine prekladace maju nieco
ekvivalentne. Inak ano, je to nestandardne, neprenostelne atd.

Druha vec, co urcite robite zle, je nasobenie adresy dvomi, pozor, vdaka
pravidlam smernikovej aritmetiky ak pricitavate integer k smerniku, tak sa
ten integer automaticky nasobi velkostou cieloveho typu smernika.
Inaksie povedane, (int16_t*)&DATA+ADRESA*N ukazuje na N-ty int16_t, nie na
N-ty byte.

Tretia vec je, ze sa da pouzit aj 

union {
  struct __attribute__((packed)) {
    int16_t x;
    int16_t y;
  };
  uint16_t h[2];
} DATA;

hoci anonymne vnorene struktury su asi vec co pribudla az v C11 a v gcc pre
C99 je to rozsirenie.

Stvrta vec je tzv type punning, t.j. pristupovanie k pod-objektom objektu
cez smerniky (alebo cez ten union). Toto je vec kontroverzie a dlheho
rozpravania, a agresivna optimalizacia prekladaca s tym moze mat problem.

Piata vec je esteticka, premennym sa nema davat meno ktore ma velke
pismena, to sa obvykle dava symbolom definovanym pomocou #define.

wek

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

>Asi to mate jinak/sloziteji, nez je v mailu, tohle by asi fungovalo 
>jestli jsem neco neprehlednul.
>Na jake je to platforme? Treba u 32b je struktura casto dost derava, 
>protoze se polozky ruzne zarovnavaji.
>A i jinak je to dost spatny pristup, program muze byt tezko prenositelny 
>a zavisly na vsem moznem nastaveni prekladace...
>
>Dne 26.10.2023 v 12:41 Martin Záruba napsal(a):
>>
>> Tak s tím teď taky bojuji a něco dělám špatně. Mám strukturu, pro 
>> jednoduchost takto
>>
>> structtDATA {
>> int16_tx;
>> int16_ty;
>> }DATA;
>> byte buf[2];
>> uint16_t ADRESA;
>>
>> Potřebuji do ní zapisovat tak, jako by to bylo pole, tedy jakoby x 
>> bylo DATA[0] a y bylo DATA[1].
>>
>> Napsal jsem to takto:
>>
>> int16_t*ADATA=(int16_t*)&DATA+ADRESA*2;
>> *ADATA=buf;
>> A očekával jsem, že jestliže pointer ADATA je typu int16_t, bude se to 
>> chovat tak, že pokud do ADRESA dám 0 zapíšou se dva byte z buf do 
>> proměnné x, pokud dám do ADRESA 1, zapíšou se do y.
>> Ale nefunguje to. Co je blbě?
>> Je mi jasné, že asi jednodušší je použít memcpy, ale já bych rád 
>> věděl, co dělám blbě.
>> -- 
>>
>> Martin Záruba
>>
>



Další informace o konferenci Hw-list