Pretypovani ukazatele struktury na bajt

David Obdrzalek David.Obdrzalek na mff.cuni.cz
Úterý Únor 25 19:16:15 CET 2020


Díky za precizní vysvětlení. 
Tak jsem to nakonec vlastně domyslel v souladu s normou :-)))

----
Hlavní chybu jsem myslím udělal v tom, že jsem nezpozoroval znaménkovost 
hexadecimální konstanty. Tu pak normou nedefinované chování shiftu při posouvání 
signed typu "přes rozsah" kvalitně využilo.

Pokusy na konstantách se mi ale povedly, protože tu chybu odhalily. Kdybych místo 
0xAD vzal něco < 0x80, tak by se moje přehlédnutí neprojevilo a já žil dál v 
nevědomosti...

A uplně na závěr, když jsem se podíval, jaký kód se vygeneruje pro (špatně napsané)
hdr.ident = c | d << 8 | ((uint32_t)e) << 16 | ((uint32_t)f) << 24;
tak je to udělané tak, aby to nedefinované chování bylo za běhu stejné, jako když 
jsem tam fouknul konstanty, jejichž uložení zařídil kompilátor. To je krásný, že to 
je konzistentní :-)


D.O.


On 25 Feb 2020 at 17:49, Jan Waclawek wrote:
> >tak se 
> >spoléhám na weka, že to vysvětlí :-)
> 
> :-(
> 
> > Nerozumím ale tomu, že 0xADDE přiřazeno do 32bit unsigned se roztáhne do 32bit
> > unsigned bez znamínka (zde implicitně), 
> 
> 0xADDE je kladna konstanta >32767 ktora nie je reprezentovatelna v int
> (t.j. v avr_gcc int16_t), takze jeho typ je unsigned int (avr_gcc:
> uint16_t), vid dole.
> 
> 
> > ale 0xAD se po posunutí o 8 doleva a pak
> > přiřazení do 32bit unsigned (opět implicitně) roztáhne znamínkově.
> 
> V skutocnosti tu nejde o konverziu, ale sa jedna o vedlajsi efekt
> nedefinovaneho spravania, 0xAD ma implicitny typ int (t.j. v avr_gcc
> int16_t), a 0xAD << 8 je 0xAD00= co je >32767 t.j. v int to nie je
> reprezentovatelne, 
> gcc v tomto pripade moze urobit uplne cokolvek, aj prekvapenie; a aj to
> obcas v mene optimalizacie robi, takze na to pozor.
> 
> C99 6.5.7#4
> The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits
> are filled with
> zeros.
> [...]
> If E1 has a signed
> type and nonnegative value, and E1 × 2^E2 is representable in the result
> type, then that is
> the resulting value; otherwise, the behavior is undefined.
> 
> 
> 
> >> Ale to s tím hextem že je vždy znamínkový se mi nějak nezdá, měl jsem za to, že ten
> >> postup je "když se vejde do int tak int, když ne, tak unsigned int, když ne, tak
> >> long int atd.".
> 
> Ano, pre hexadecimalnu konstantu to plati, pre decimalnu nie, ta je vzdy
> znamienkova.
> C99, 6.4.4.1#5, je tam na to tabulka.
> 
> wek




Další informace o konferenci Hw-list