Newsgroup: it.hobby.elettronica.digitale
Titolo: Dereferencing type-punned pointer will break strict-aliasing rules

 
Mi sono finalmente imbattuto anche in questo errore ;)
Il codice non è mio ma fa parte di un esempio fornito da un produttore.
 
*(UINT16*)&sMsgBuffer.sHeader.bCmdExt0 = iLeTOi(adi);
 
dove bCmdExt0 è di tipo UINT8, mentre iLeTOi restituisce un UINT16.
Questa la struttura di sHeader:
 
typedef struct ABP_MsgHeaderType {
    UINT8    bSourceId;
    UINT8    bDestObj;
    UINT16   iInstance;
    UINT8    bCmd;
    UINT8    bDataSize;
    UINT8    bCmdExt0;
    UINT8    bCmdExt1;
}
 
Nel mio caso UINT8 e UINT16 vengono espansi come uint8_t e uint16_t.
 
Se capisco bene vuole spalmare in un colpo solo il valore restituito da 
iLeTOi nei due byte composti da bCmdExt0 e bCmdExt1 (*).
 
Per evitare il warning evidenziato dal compilatore (avr-gcc) pensavo di 
fare una cosa del genere:
 
UINT16 t = iTOiLe(adi + 1);
memcpy(&sMsgBuffer.sHeader.bCmdExt0, &t, sizeof(UINT16));
 
Ha senso? Oppure il warning in questo caso è "tollerato" e non mi devo 
aspettare malfunzionamenti?
 
Marco
 
(*) il codice originario non è specifico per AVR, ma è genericamente 
scritto in C. Mi chiedo come possa funzionare nel caso in cui 
l'allineamento non sia a 8 bit...

 l'allineamento non sia a 8 bit...
 
diciamo che e' scritto in C genericamente non portabile senza verifiche 
sul campo
 

 l'allineamento non sia a 8 bit...
se il processore gestisce il byte swap ok, se no ciccia :-)
AA
 

 sul campo
 
 
Ok, ricevuto.
Marco
 
 

 Dove ENDIAN è una macro per aggiustare l' endianness della CPU :-)
 
 
In realtà, iLeTOi tiene già conto dell'endianness (è definita 
diversamente nei due casi).
 
Ciao!
Marco

 
 
ho dato una rapidissima scorsa ed effettivamente sono quelle zone 
d'ombra dell'ottimizzatore ( almeno cosi' mi e' parso )
 
forum ? what's forum ? io parlo solo "news di usenet" ;-)


 d'accordo!
No, in questo caso funziona sempre perche' l'allineamento
e' congruente e l' overlay e' completo.
Il problema delle union e' l' eventuale padding di elementi
introdotti da strutture , ma in questo caso non ci sono
problemi.
AA.
 


Premesso che all'atto pratico hai ragione, se proprio vogliamo essere 
pignoli la soluzione proposta potrebbe dare qualche problema su qualche 
compilatore particolarmente solerte nell'ottimizzare.
 
Le union non sono nate per convertire da un tipo ad un altro. Il loro 
scopo originario era quello di poter avere una struttura dati flessibile 
in modo da poter rappresentare con lo stesso tipo, più tipi diversi.
Tutti gli standard, infatti, proibiscono di scrivere in un campo per poi 
leggere dall'altro: è undefined behaviuor.
 
Perché tutto ciò? Perché se non c'è aliasing fra tipi diversi i 
compilatori possono ottimizzare di più.
Esempio semplificato:
 
#include <stdio.h>
#include <stdint.h>
 
union U
{
     uint8_t  bytes[2];
     uint16_t word;
};
 
 
int main(void)
{
     union U a;
 
     a.word = 3;
     a.bytes[0] = 0;
     a.bytes[1] = 0;
     printf("%d\n", a.word);
     return 0;
}
 
Quanto vale alla fine a.word?
Un compilatore particolarmente ottimizzoso, potrebbe cachare in un 
registro quanto scritto in a.word, e siccome successivamente non c'è 
nessun altro accesso diretto ad a.word, stampare il valore precedente, 
ovvero 3.
 
In realtà tutti i compilatori seri sanno che gli utenti sono abituati a 
fare queste cose e trattano questi casi a dovere.
 
Ma, se lo scopo è scrivere codice generico e portabile, consiglio di non 
usare mai le union per fare le conversioni.
 
-- 
  _|/ Francesco Sacchi - Develer S.r.l., R&D dept.
   |\ 
http://www.develer.com/
 - 
http://www.bertos.org
 

 l'allineamento non sia a 8 bit...
 
Funziona fintato che bCmdExt0 è ad un indirizzo allineato, e questo è 
vero per come è fatta la struttura adesso... ma affidarsi al fatto che 
si conosce l'implementazione non è buona cosa, soprattutto se si tratta 
di codice di una libreria che potrebbe cambiare.


 usare mai le union per fare le conversioni.
Parole sante.
AA.
 

 non sono proprio quelli voluti.
 
In realtà i compilatori sono liberi di riordinare le istruzioni come 
vogliono, rispettando certi vincoli. Il vincolo fondamentale è il 
concetto di aliasing espresso sopra.
 
 
-- 
  _|/ Francesco Sacchi - Develer S.r.l.
   |\ 
http://www.develer.com/
 - 
http://www.bertos.org/