 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Markus Schaaf Guest
|
Posted: Tue Feb 01, 2005 9:23 am Post subject: Padding in einfachen char-struct |
|
|
Ich hätte gerne mal ein paar Kommentare/Erfahrungen zu Folgendem:
Für ein einfaches IO-Protokoll brauche ich Byteströme, die
irgendwie strukturiert sind. Die reine Lehre wäre, zum Schreiben
und Lesen Paare von Funktionen zu benutzen, die intern mit »memcpy«,
Zeigerarithmetik usw. arbeiten. Das wird mir jedoch schnell zu
unübersichtlich und ineffizient. Also mache ich das eher so:
template< unsigned len >
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen. Allerdings kenne ich auch nicht viele Compiler, und
auch keine exotischen Architekturen (Embedded-Controller wären von
Interesse).
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Feb 01, 2005 10:14 am Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | Ich hätte gerne mal ein paar Kommentare/Erfahrungen zu
Folgendem: Für ein einfaches IO-Protokoll brauche ich
Byteströme, die irgendwie strukturiert sind. Die reine Lehre
wäre, zum Schreiben und Lesen Paare von Funktionen zu
benutzen, die intern mit »memcpy«, Zeigerarithmetik usw.
arbeiten. Das wird mir jedoch schnell zu unübersichtlich und
ineffizient. Also mache ich das eher so:
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt
kein Compiler auf die Idee, in solche reinen »char«-Strukturen
Padding einzufügen. Allerdings kenne ich auch nicht viele
Compiler, und auch keine exotischen Architekturen
(Embedded-Controller wären von Interesse).
|
Der Compiler darf. Typischerweise würde ich es nur am Ende
erwarten, falls es überhaupt vorkommt.
In der Praxis benutze ich auch so was ähnlich. In meinem Fall
nicht mit templates sondern mit generiertem Code (was sinnvollen
getter und setter erlaubt). Funktionniert's zwar tadellos bei
mir, aber die Portabilität ist hier nicht gefragt.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Tue Feb 01, 2005 10:39 am Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen. Allerdings kenne ich auch nicht viele Compiler, und
auch keine exotischen Architekturen (Embedded-Controller wären von
Interesse).
powerpc-rtems-g++ --version
powerpc-rtems-g++ (GCC) 3.2.3 |
Copyright (C) 2002 Free Software Foundation, Inc.
.... (siehe <http://www.rtems.com>)
Weiß nicht, ob der exotisch genug ist - jedenfalls fügt er kein
Padding ein, selbst wenn man 'String<1>'-Member reinpackt.
'short' bzw. 'int'/'long' werden dagegen auf durch 2 bzw. 4
teilbare Adressen gelegt. Compilerspezifische Switches hab
ich jetzt auf die Schnelle nicht angeguckt.
MfG
Falk
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Tue Feb 01, 2005 11:24 am Post subject: Re: Padding in einfachen char-struct |
|
|
<kanze (AT) gabi-soft (DOT) fr> schrieb im Newsbeitrag
news:1107252851.630660.289080 (AT) f14g2000cwb (DOT) googlegroups.com...
| Quote: | Markus Schaaf wrote:
Ich hätte gerne mal ein paar Kommentare/Erfahrungen zu
Folgendem: Für ein einfaches IO-Protokoll brauche ich
Byteströme, die irgendwie strukturiert sind. Die reine Lehre
wäre, zum Schreiben und Lesen Paare von Funktionen zu
benutzen, die intern mit »memcpy«, Zeigerarithmetik usw.
arbeiten. Das wird mir jedoch schnell zu unübersichtlich und
ineffizient. Also mache ich das eher so:
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt
kein Compiler auf die Idee, in solche reinen »char«-Strukturen
Padding einzufügen. Allerdings kenne ich auch nicht viele
Compiler, und auch keine exotischen Architekturen
(Embedded-Controller wären von Interesse).
Der Compiler darf. Typischerweise würde ich es nur am Ende
erwarten, falls es überhaupt vorkommt.
|
Am Beginn darf er nicht.
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Tue Feb 01, 2005 6:23 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen. Allerdings kenne ich auch nicht viele Compiler, und
auch keine exotischen Architekturen (Embedded-Controller wären von
Interesse).
|
Ich hab es mit allen mir zur Verfügung stehenden Compilern ausprobiert,
inkl. einem für einen DSP von ADI, keiner hat da Padding gemacht.
Ich würde aber auf jeden Fall noch ein assert(sizeof(Header)==1
irgendwo unterbringen.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Tue Feb 01, 2005 6:38 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | Ich hätte gerne mal ein paar Kommentare/Erfahrungen zu Folgendem:
Für ein einfaches IO-Protokoll brauche ich Byteströme, die
irgendwie strukturiert sind. Die reine Lehre wäre, zum Schreiben
und Lesen Paare von Funktionen zu benutzen, die intern mit »memcpy«,
Zeigerarithmetik usw. arbeiten. Das wird mir jedoch schnell zu
unübersichtlich und ineffizient. Also mache ich das eher so:
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen. Allerdings kenne ich auch nicht viele Compiler, und
auch keine exotischen Architekturen (Embedded-Controller wären von
Interesse).
|
100_TOR $ cxx/version
Compaq C++ V6.2-048 for OpenVMS Alpha V7.3
legt dort nirgends Padding ein. Durch einen compiletime assert könnte
man ja noch sicher stellen, das es einen Fehler gibt, wenn der code von
einem Compiler übersetzt wird, bei dem sizeof Header != 18 ist. Selbst
wenn es einen Compiler gäbe, der es anders macht, gäbe es sicher auch
irgend welche pragmas und/oder Schalter, um ihm dieses abzugewöhnen.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Tue Feb 01, 2005 7:34 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Danke allen für die Kommentare. Natürlich ist da ein Compile-
Time-Assert, aber der würde das Problem nur anzeigen, nicht
beheben. Ich will den Code möglichst nicht mehr anfassen müssen,
falls der mal "portiert" werden muß.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Mario Schunda Guest
|
Posted: Tue Feb 01, 2005 10:30 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Hallo Markus
So weit mir bekannt ist geht das mit einer
#pragma pack(1) // hier steht wie er packen muss
und endet mit
#pragma pack() // wieder auf compiler default stellen
Sehe dann so aus.
#pragma pack(1)
template< unsigned len >
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
....
#pragma pack()
Unter dem gcc gibt es da noch die __attribute__ Anweisung.
Wie die genaue Syntax ist weis ich nicht aus dem Kopf.
Mario
PS: Hoffe das pack(x) kennt jeder Compiler.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Matthias Guest
|
Posted: Wed Feb 02, 2005 6:40 am Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
|
Mal ne andere Frage. Warum dieses seltsame String Konstrukt?
Wo liegt der Sinn, für jede neue Länge von Strings eine eigene Klasse
anzulegen?
Was, wenn du hundert Strings hast, die alle unterschiedlich lang sind?
Wilst du dafür 100 Klassen anlegen? Das macht irgendwie keinen Sinn, da
sie sich alle gleich verhalten. Klingt nach ziemlichem Overhead.
--
Regards,
Matthias
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Roland Frank Guest
|
Posted: Wed Feb 02, 2005 11:32 am Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf wrote:
| Quote: | Danke allen für die Kommentare. Natürlich ist da ein Compile-
Time-Assert, aber der würde das Problem nur anzeigen, nicht
beheben. Ich will den Code möglichst nicht mehr anfassen müssen,
falls der mal "portiert" werden muß.
|
Tut mir leid, wenn ich hier schlechte Nachrichten überbringen muss:
a) Im Standard ist zwar definiert, dass sizeof(char) == 1 ist,
ABER
b) ist im gleichen Standard völlig offengelassen, welche
Anzahl von bits ein char eigentlich hat.
Mit anderen Worten:
unsigned char test[18];
kann eine Struktur von von 144 bits (char hat 8 bits) oder
auch von 1152 bits sein (char hat 64 bits) und trotzdem
kann in beiden Fällen gelten sizeof(test) == 18.
Der Assert auf die Strukturgröße hilft dir nur wenn der Compiler
beschließt die Struktur zu padden; was er tun darf oder bleiben
lassen kann, je nach Laune.
Im Falle von Padding ist es durchaus möglich, daß der Compiler
dir einen switch (z.B. in Form eines #pragma wie bei vc++)
zur Verfügung stellt um das zu beeinflussen, muss aber nicht.
Wenn du wirklich auch exotische Architekturen in deine
Portierungsüberlegungen einbeziehen willst, dann bleibt dir
nur übrig, dieses Teil im Portierungsguide gut zu dokumentieren :-)
Gruß
Roland
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Wed Feb 02, 2005 12:12 pm Post subject: Re: Padding in einfachen char-struct |
|
|
"Matthias" <nospam (AT) digitalraid (DOT) com> schrieb:
| Quote: | Markus Schaaf wrote:
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Mal ne andere Frage. Warum dieses seltsame String Konstrukt?
|
Es ist die idiomatische Methode, aus einem Array ein First-Class-Object
zu machen. Was der Dreh- und Angelpunkt bei der ganzen Geschichte ist.
| Quote: | Wo liegt der Sinn, für jede neue Länge von Strings eine eigene Klasse
anzulegen?
Was, wenn du hundert Strings hast, die alle unterschiedlich lang sind?
Wilst du dafür 100 Klassen anlegen?
|
Ich lege gar nichts an. Das macht der Compiler automatisch.
| Quote: | Das macht irgendwie keinen Sinn, da
sie sich alle gleich verhalten. Klingt nach ziemlichem Overhead.
|
Im Gegenteil, es reduziert ihn. Du kannst aber gerne Verbesserungsvorschläge
machen.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Schaaf Guest
|
Posted: Wed Feb 02, 2005 1:05 pm Post subject: Re: Padding in einfachen char-struct |
|
|
"Roland Frank" <roland.frank.no-spam (AT) gmx (DOT) info> schrieb:
| Quote: | b) ist im gleichen Standard völlig offengelassen, welche
Anzahl von bits ein char eigentlich hat.
|
Es ist implementation-defined, d.h. jeder Compiler dokumentiert diesen
Wert durch Setzen des Makros »CHAR_BIT« und durch Spezialisierung des
Templates »numeric_limits«. (Darüber hinaus ist die Anzahl der Bits in
einem »char« sowohl für meine Frage als auch für mein Programm völlig
bedeutungslos: Es handelt sich um ein serielles Text-Protokoll. Ob die
einzelnen Zeichen auf dem Draht 7 Bit oder im Speicher 9 haben, ändert
nichts.)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thorsten Nitz Guest
|
Posted: Wed Feb 02, 2005 6:30 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Markus Schaaf schrieb:
| Quote: |
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen.
|
Im vergangenen Jahrhundert ist mir mal einer begegnet, der hat
Strukturen stets auf 8 Byte aligned. Da die Member von Header Strukturen
sind, hätte er hinter preamble 6 Byte eingefügt. Irrsinnigerweise hatte
er sogar ein #pragma(pack). Leider weiß ich den Namen und Hersteller
dieses Compilers nicht mehr. Möglicherweise war das im Zusammenhang mit
dem zu Recht vergessenen BEtriebssystem VRTX.
Zeitgenössische Compiler mit solchem Verhalten sind mir nicht bekannt.
Aber man muss immer damit rechnen, dass irgend jemand mit lex und yacc
einen neuen Compiler für eine selbstgestrickte Plattform zusammenbrät
und auf die Menschheit loslässt. Deswegen gibt es ja die Reine Lehre.
Oder man geht das kalkulierte Risiko ein, mal eine Plattform nicht ohne
weiters unterstützen zu können.
Übrigens ist das hier ein klasse Beispiel für boost::static_assert:
boost::static_assert(sizeof(Header)
== sizeof(preamble) + sizeof(sender) + sizeof(receiver));
sagt Dir schon zur Compilezeit, ob gepadded wird.
Tschö, wa!
Thorsten
Allerdings kenne ich auch nicht viele Compiler, und
| Quote: | auch keine exotischen Architekturen (Embedded-Controller wären von
Interesse).
|
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Wed Feb 02, 2005 7:46 pm Post subject: Re: Padding in einfachen char-struct |
|
|
"Thorsten Nitz" <T.Nitz (AT) epost (DOT) de> schrieb im Newsbeitrag
news:36ckkvF50nr93U1 (AT) individual (DOT) net...
| Quote: | Markus Schaaf schrieb:
template< unsigned len
struct String {
unsigned char bytes[len];
};
struct Header {
String<2> preamble;
String<8> sender;
String<8> receiver;
...
Nun die Frage: Soweit ich das bisher beobachten konnte, kommt kein
Compiler auf die Idee, in solche reinen »char«-Strukturen Padding
einzufügen.
Im vergangenen Jahrhundert ist mir mal einer begegnet, der hat
Strukturen stets auf 8 Byte aligned. Da die Member von Header Strukturen
sind, hätte er hinter preamble 6 Byte eingefügt. Irrsinnigerweise hatte
er sogar ein #pragma(pack). Leider weiß ich den Namen und Hersteller
dieses Compilers nicht mehr. Möglicherweise war das im Zusammenhang mit
dem zu Recht vergessenen BEtriebssystem VRTX.
Zeitgenössische Compiler mit solchem Verhalten sind mir nicht bekannt.
Aber man muss immer damit rechnen, dass irgend jemand mit lex und yacc
einen neuen Compiler für eine selbstgestrickte Plattform zusammenbrät
und auf die Menschheit loslässt. Deswegen gibt es ja die Reine Lehre.
Oder man geht das kalkulierte Risiko ein, mal eine Plattform nicht ohne
weiters unterstützen zu können.
Übrigens ist das hier ein klasse Beispiel für boost::static_assert:
boost::static_assert(sizeof(Header)
== sizeof(preamble) + sizeof(sender) + sizeof(receiver));
sagt Dir schon zur Compilezeit, ob gepadded wird.
|
Das reicht leider nicht. Ich nehme mal an, Markus will die chars in Header
als ein Array ansehen. Das Problem ist, daß z.B. sizeof(String<2>) nicht 2
ergeben muß, weil in String<2> padding bytes drinnen sein können. Damit
verschiebt sich dann logischerweise alles andere dahinter.
Man muß also 2 getrennte asserts machen:
a) sizeof(String<2>) == 2 && sizeof(String<8>) == 8 // am besten in
Header
b) Dein obiges.
Generell kann es sein, daß 3 getrennte arrays in Header besser sind:
struct Header{
char preamble[2];
char sender[8];
char receiver[8];
};
Damit könnte (!) ein blöder Compiler bekehrt werden, und kein padding
zwischen den 3 einfügen, wohingegen einer der generell jede Struktur auf
x-bytes alignt sehr wohl dazwischen was einbaut.
Wie gesagt, alles Konjunktiv, Garantie gibts keine (aber unsicherer dürfte
es meiner Meinung nach nicht geworden sein - eher aber sicherer), und
sizeof(Header) kann selbst dann noch was anderes sein als 18.
Markus: Spricht was dagegen, den Zugriff über Funktionen zu machen?
struct Header
{
enum {preambleSize = 2, signalSize = 8, receiverSize = 8};
char* preamble() {return Chars;}
char* signal() {return preamble() + preambleSize;}
char* receiver() {return signal() + signalSize;}
char Chars[18];
};
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Wed Feb 02, 2005 7:50 pm Post subject: Re: Padding in einfachen char-struct |
|
|
Ups, Chars[] soll natürlich so aussehen:
struct Header
{
enum {preambleSize = 2, signalSize = 8, receiverSize = 8};
char* preamble() {return Chars;}
char* signal() {return preamble() + preambleSize;}
char* receiver() {return signal() + signalSize;}
char Chars[preambleSize + signalSize + receiverSize];
};
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|