Newsgroup: it.comp.lang.c++
Titolo: allineamento strutture VC

ho un problema con la seguente struttura (corrispondente ad un record di
un file)
typedef struct line_2d
    {
    Elm_hdr	ehdr;	    /* element header */
    Disp_hdr	dhdr;	    /* display header */
    Point2d	start;	    /* starting point */
    Point2d	end;	    /* ending point */
    } Line_2d;
uso:
#pragma pack(2) (e' a 16bit) ;
Elm_hdr e' lunga 8 words, Disp_hdr 11 words, ma start che dovrebbe
iniziare alla 19^ word slitta invece alla 20 (quindi non riesco a
leggere correttamente i dati dal file).
Le strutture sono degli include di un altro compilatore con il quale non
ho mai avuto problemi.
grazie in anticipo
--
Greetings, Alessandro
http://www.esalab.it
Pesaro, Italy
--== Sent via Deja.com 
http://www.deja.com/
 ==--
---Share what you know. Learn what you don't.---

 leggere correttamente i dati dal file).
E' comune padding; il compilatore e' libero di inserire "buchi" in
modo da allineare gli elementi della classe (o della struttura) nella
maniera piu' efficiente possibile.
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

leggere correttamente i dati dal file).
E' proprio la direttiva #pragma pack(2) a far si' che i membri
della tua struttura siano allineati a due byte.
Ogni membro della tua struttura occupa esattamente
member_size + member_size % pack_value;
Quindi per Disp_hdr = 11 bytes:
11 + 11 % 2 = 12 bytes
Per questo il membro start è posto al 20esimo byte
((Elm_hdr = 8) + 12).
Oreste Notelli

maniera piu' efficiente possibile.
Per eliminare tale "buco" specifica un allineamento a 1 (1 byte),
penso che il tuo compilatore dovrebbe consentirlo.
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------


ICQ #34602650

la struttura e leggere invece i singoli elementi (mooolto dispendioso).
Sul dispendio non penso sia facile fare previsioni...
Dato che presumibilmente l'input viene da un file su disco, anche se
il programma leggesse un solo char, generalmente sotto l'applicativo
c'e` un sistema di cache che legge in un colpo solo almeno tutto un settore
(o piu` facilmente piu` settori)... una lettura su disco avrebbe quindi luogo
quando non ci sono piu` dati sul buffer. Salvo che le letture non siano molto
distanti tra loro, presumibilmente (ma non e` detto...)
leggere singoli valori e` sostanzialmente la stessa cosa che
leggere tutto in un colpo.
Comunque io adotterei un sistema del tipo leggere una pagina del file
in un buffer e poi inserire i dati dal buffer al singolo record. Permette
di non fare ipotesi sulla cache e di consentire un approccio OO nella
realizzazione della classe (ovvero ridurre una operazione su un oggetto
composto in operazioni sui sotto-oggetti).


 della tua struttura siano allineati a due byte.
no questo va bene; sono pero' riuscito a trovare il problema, avevo u n
typedef che "sembrava" di due byte ed invece ne prendeva 4 in VC++6.0;
cosi' e' 2 bytes:
typedef struct symbology
    {
    unsigned	short style:16;	// element line style
    } Symbology;
cosi' e' 4:
typedef struct symbology
    {
    unsigned	style:16;	// element line style
    } Symbology;


 in un buffer e poi inserire i dati dal buffer al singolo record. 
Io in un caso ho fatto così. Si trattava di un indice che doveva essere
caricato in un array di strutture. La soluzione di leggere direttamente
nel vettore di strutture mi costringeva a impostare l'allineamento ad un
byte a scapito delle prestazioni in tutto il programma. Ho preferito
leggere tutto l'indice in un buffer, quindi ho fatto il "trasbordo" dei
dati nel vettore.


dati nel vettore.
Volevo aggiungere che comunque non dovrebbero esserci problemi
quando l'I/O di un oggetto grosso e` implemetato come I/O delle
componenti. Ovvero (uso le struct per semplicita` e sempre per semplicita`
evito l'uso di stringhe):
struct TRecord {
  float a;
  long c;
  char b;
  unsigned long d;
}
ostream& operator<<(ostream& os, TRecord& Rec) {
  os << a << c << b << d;
  return os;
}
istream& operator>>(istream& is, TRecord& Rec) {
  is >> a >> c >> b >> d;
  return is;
}
In questo modo non dovrebbero esserci problemi.
La situazione cambia ovviamente se si cerca di riempire
un buffer su cui viene mappato (tramite union o puntatore...)
un TRecord, ma questa e` in realta` una cosa che richiede
implicitamente o esplicitamente un cast, e sappiamo bene
che i cast sono operazioni molto delicate. 
