sizeof liefert unerwartetes ergebniss
-
hallo leutz,
sehe gerade den baum vor lauter wäldern nicht ..
fuer folgende struktur haette ich angenommen dass sizeof als groesse die anzahl an bytes zurueckliefert:
typedef unsigned char uchar; typedef unsigned long ulong; struct T_ID3v2Header { uchar id[3]; uchar t_majVer; uchar t_minVer; uchar t_flags; ulong t_size; }; int main(int argc, char *argv[]) { size_t temp = sizeof(T_ID3v2Header); return 0; }ich zaehle fuer obige struktur 10 bytes aber bekomme als ergebniss 12

jemand ne idee warum das so ist?
thnx vorab.
-
padding
-
Strukturenoptimierung.
-
lässt sich compilerspezifisch abstellen:
#pragma pack(push,1)
// struktur
#pragma pack(pop)
-
sorry,
ausgiebiger googlen haette mir das posten erspart:
padding ist das schluesselwort:
bei visual kann man unter projekt-einstellungen das padding einstellen.
das war bei mir auf standard eingestellt. waehlt man dort 1Byte, dann liefert sizeof das richtige ergebnis.trotzdem danke.
gruss
-
Lieber manuell viá #pragma machen, da Padding ja nicht aus Spaß erfunden wurde, außerdem wird das sicher nicht in jedem deiner Projekte benötigt...
-
pepe75 schrieb:
waehlt man dort 1Byte, dann liefert sizeof das richtige ergebnis.
sizeof liefert _immer_ das richtige Ergebnis, egal welches Padding. Das die Struktur abhängig vom Padding unterschiedliche Größen hat ist kein Fehler.
-
Ist das nicht prinzipiell ein Fehlerherd bei statischen/dynamischen Bibliotheken?
Angenommen man hat :
struct data { char foo; int bar; }; void foobar(data& dat);Dann kann es doch durchaus sein dass die kompilierte Funktion der Lib folgendes erwartet
Byte 1: foo
Byte 2: bar
Byte 3: bar
Byte 4: bar
Byte 5: baraber der Nutzer ungewollt folgendes übergibt
Byte 1: foo
Byte 2: padding
Byte 3: padding
Byte 4: padding
Byte 5: bar
Byte 6: bar
Byte 7: bar
Byte 8: bar
-
Icematix schrieb:
Ist das nicht prinzipiell ein Fehlerherd bei statischen/dynamischen Bibliotheken?
Ja. Deshalb fängt bei mir jeder Header für Bibliotheksfunktionen so an:
#ifdef __BORLANDC__ # pragma option -RT- # pragma option -b # ifdef __WIN32__ # pragma option -a4 # pragma option -pc # else # pragma option -a2 # pragma option -po # endif #endifund so werden sie beendet:
#ifdef __BORLANDC__ # pragma option -RT. # pragma option -b. # pragma option -a. # pragma option -p. #endifmfg Martin
-
mgaeckler schrieb:
Icematix schrieb:
Ist das nicht prinzipiell ein Fehlerherd bei statischen/dynamischen Bibliotheken?
Ja. Deshalb fängt bei mir jeder Header für Bibliotheksfunktionen so an:
#ifdef __BORLANDC__ # pragma option -RT- # pragma option -b # ifdef __WIN32__ # pragma option -a4 # pragma option -pc # else # pragma option -a2 # pragma option -po # endif #endifund so werden sie beendet:
#ifdef __BORLANDC__ # pragma option -RT. # pragma option -b. # pragma option -a. # pragma option -p. #endifmfg Martin
Interessant und was macht das jetzt genau?
-
Irgendwelche Annahmen dahingehend, wie das Layout einer Struktur/Klasse im Speicher aussieht, sollten einfach nicht gemacht werden. Wenn es um Daten-Ein/Ausgabe geht, muss man sich eben die Bytes manuell zusammensetzen etc.
-
krümelkacker schrieb:
Irgendwelche Annahmen dahingehend, wie das Layout einer Struktur/Klasse im Speicher aussieht, sollten einfach nicht gemacht werden. Wenn es um Daten-Ein/Ausgabe geht, muss man sich eben die Bytes manuell zusammensetzen etc.
Das sehe ich nicht so. Header in Dateiformaten kann man ruhig in so structs packen, das ist nämlich saupraktisch. Dazu noch ein wenig #pragma oder __attribute__((packed)) und gut ists. Falls Du gewöhnlich Software für MS udn Linux codest, kannst Du natürlich mit #if beides machen. Falls Du sogar für zukünftige Plattformen baust, die noch keiner kennt, mach's halt Byteweise.
-
volkard schrieb:
das ist nämlich saupraktisch
genau
-
Kóyaánasqatsi schrieb:
Interessant und was macht das jetzt genau?
#pragma option -RT-Das schaltet Runtimetypeinformation aus.
#pragma option -bSorgt dafür, daß enums die gleiche Größe wie ints haben.
#pragma option -aXSchaltet das Padding in Strukturen auf X Bytes.
#pragma option -pXSetzt die Aufrufkonventionen.
Am Ende werden einfach alle Parameter wieder auf den Ursprungswert gesetzt.
mfg Martin
-
mgaeckler schrieb:
Am Ende werden einfach alle Parameter wieder auf den Ursprungswert gesetzt.
Auf den Ursprungswert oder den Defaultwert?
Damit meine ich, soll man nicht#pragma option push/popkennen und benutzen?
-
volkard schrieb:
mgaeckler schrieb:
Am Ende werden einfach alle Parameter wieder auf den Ursprungswert gesetzt.
Auf den Ursprungswert oder den Defaultwert?
Damit meine ich, soll man nicht#pragma option push/popkennen und benutzen?
Hab jetzt gerade kein BC++ zur Hand. Aber soweít ich weiß bewirkt dieses Pragma
# pragma option -RT.daß die option RT auf den anfänglichen Wert, wie er am Beginn der Datei war, gesetzt wird.
#pragma option push/popKenne ich nicht.
Ich benutzte teilweise noch Borland C++ 5.02 (nicht den Builder), es kann sein, daß neuere Compiler hier etwas besser sind.
mfg Martin