gcc alignment bug
-
Ich meine GCC alignment-Fehler.
GCC crasht nicht ! Aber doch mein Program. Ich weiss warum. Ich werde einfacher Beispiel geben - mein Kode ist mehr kompliziert.
In einem C-file:class A { public: char c; int fd; void Modify () { int fd = 0; } }
in anderem:
class C { public: A a; B b; }
Denn Code:
C test; test.a.Modify ();
modifiziert nicht nur variable test.a.fd aber auch variable test.b
und deswegen mein Program crascht! wenn ich auf den Assembler Kode sehe von der Funktion A::Modify da steht:mov %eax,0x4(%ebx) // eax -> ebx[4] = (A * this)[4]
ebx enthaelt den Wert des this-Zeigers, als ob A ist word-gerichtet!!!!
Dieser Fehler beobachte ich mit verschidenen GCC-versionen
Und ich frage: kann es sein das durch verschidene H-files kommt es zu verschidenen default-Richtungen?
-
itman schrieb:
void Modify () { int fd = 0; }
du meinst sicher fd = 0.
mov %eax,0x4(%ebx) // eax -> ebx[4] = (A * this)[4]
ebx enthaelt den Wert des this-Zeigers, als ob A ist word-gerichtet!
Woran siehst du da eine Word-Ausrichtung? Es wird auf ein dword zugegriffen, was sich 4 Bytes vom Anfang der Instanz befindet. Sieht nach dword-Ausrichtung aus. sizeof(A) müsste 8 sein.
Und ich frage: kann es sein das durch verschidene H-files kommt es zu verschidenen default-Richtungen?
Nur, wenn dieselbe Klasse verschieden definiert ist (Verstoß gegen die One-Definition-Rule) oder wenn verschiedene Compilereinstellungen verwendet werden.
-
sizeof (a) == sizeof (A) == 5
sicher? da glaub ich nicht dran.
-
Helium schrieb:
sizeof (a) == sizeof (A) == 5
sicher? da glaub ich nicht dran.
100 prozent!!! das pruefe ich auch sowohl mit cout<<sizeof als auch mit GDB
-
Bashar schrieb:
itman schrieb:
void Modify () { int fd = 0; }
du meinst sicher fd = 0.
mov %eax,0x4(%ebx) // eax -> ebx[4] = (A * this)[4]
ebx enthaelt den Wert des this-Zeigers, als ob A ist word-gerichtet!
Woran siehst du da eine Word-Ausrichtung? Es wird auf ein dword zugegriffen, was sich 4 Bytes vom Anfang der Instanz befindet. Sieht nach dword-Ausrichtung aus. sizeof(A) müsste 8 sein.
sorry, natuerlich
void Modify () { fd = 0; }
und ueber Word-Ausrichtung: Word Groesse ist 32 bit = 4 byte. Wenn es byte-Ausrichtung ware denn assembler Kode wuerde:
mov %eax,0x1(%ebx) // eax -> ebx[1] = (A * this)[1]
weil das erste Klass-Mitglied ist nur 1 byte gross
-
Mal kurz zur Terminologie: ein Word sind 2 Bytes, ein DWord sind 4 Bytes. Frag mich nicht warum, das hat historische Gründe. Dann wär das ja geklärt, du erwartest also an einer Stelle Byte-Ausrichtung, aber der Compiler gibt dir eine DWord-Ausrichtung.
Dazu muss man zunächst sagen, dass DWords (also z.b. ints) auf manchen 32-Bit-Architekturen nicht an Adressen stehen können, die nicht durch 4 teilbar sind. Es gibt also Ausrichtungszwang. Wird dieser verletzt, wirft der Prozessor eine Exception, die normalerweise in einer Beendigung des Programms resultiert. Auf anderen Architekturen (z.B. Intel 80x86 ... Pentium usw.) gibt es einen schwachen Ausrichtungszwang. DWords, die an nicht durch 4 teilbaren Adressen liegen, werden wesentlich langsamer verarbeitet, als ausgerichtete.
Deshalb wird ein Compiler im Normalfall ints und andere DWords immer ausrichten. Die Klasse A nimmt also 8 Bytes ein.
Ich würd jetzt gern ein minimales Beispielprogramm sehen, was bei deiner Klasse A tatsächlich ausgibt, dass ihre Größe 5 ist. Das glaub ich nämlich nicht, ohne es zu sehen.
-
Bashar schrieb:
Mal kurz zur Terminologie: ein Word sind 2 Bytes, ein DWord sind 4 Bytes. Frag mich nicht warum, das hat historische Gründe. Dann wär das ja geklärt, du erwartest also an einer Stelle Byte-Ausrichtung, aber der Compiler gibt dir eine DWord-Ausrichtung.
Ich erwarte nicth aber, in einem C-file ist es DWord-Auschritung in anderem - Byte-Ausrichtung. Ich werde ein minimales Beispiel zu Kochen. Aber es ist nicht so leicht
Dazu muss man zunächst sagen, dass DWords (also z.b. ints) auf manchen 32-Bit-Architekturen nicht an Adressen stehen können, die nicht durch 4 teilbar sind. Es gibt also Ausrichtungszwang. Wird dieser verletzt, wirft der Prozessor eine Exception, die normalerweise in einer Beendigung des Programms resultiert. Auf anderen Architekturen (z.B. Intel 80x86 ... Pentium usw.) gibt es einen schwachen Ausrichtungszwang. DWords, die an nicht durch 4 teilbaren Adressen liegen, werden wesentlich langsamer verarbeitet, als ausgerichtete.
Das ist klar
Deshalb wird ein Compiler im Normalfall ints und andere DWords immer ausrichten. Die Klasse A nimmt also 8 Bytes ein.
Ich würd jetzt gern ein minimales Beispielprogramm sehen, was bei deiner Klasse A tatsächlich ausgibt, dass ihre Größe 5 ist. Das glaub ich nämlich nicht, ohne es zu sehen.
-
Wahrscheinlich inkludierst du in dem anderen C File ein anderes Header File, das auch A und B definiert, aber anders.
-
-
Uuuups, ich verstand es!!!!!
Das war mein Feheler. Das ist nicht die Verletzung des ODR Regels aber was Aehnliches. Naehmlich, das war #pragma(1) das ich vergiss zu loeschen
In einem C-file ist die Klasse 1-byte und in anderem - 4byte ausgerichtet. Es ist die Verltzung von der Ein-Declaration-RegelUnd mit pragma war es auch nicht sehr einfach weil es im h-File verborg wurde
-
seit wann kann man in einem C-File C++ Sachen machen?
-
???? schrieb:
seit wann kann man in einem C-File C++ Sachen machen?
Ok, in einem text-file? ist es besser?
-
Nein in einem cpp File.
-
???? schrieb:
Nein in einem cpp File.
Das ist aber egal. Fuer mich ist es bequem eine C-extension zu benutzen. Und was bedeutend ist: das es kein G++ bug ist.
-
itman schrieb:
Und was bedeutend ist: das es kein G++ bug ist.
Huch. Damit hatte jetzt wohl niemand gerechnet.
-
Shade Of Mine schrieb:
itman schrieb:
Und was bedeutend ist: das es kein G++ bug ist.
Huch. Damit hatte jetzt wohl niemand gerechnet.
Du meinst das GCC im Prinzip keine Fehler hat, oder das sie sind nicht so einfach? z.B. Kern von Linux wird nur mit GCC version 3.x korrekt kompiliert
-
itman schrieb:
Du meinst das GCC im Prinzip keine Fehler hat, oder das sie sind nicht so einfach? z.B. Kern von Linux wird nur mit GCC version 3.x korrekt kompiliert
Jo, GCC ist ziemlich Fehlerfrei - natürlich nicht ganz, aber die wahrscheinlichkeit dass du einen Bug findest ist wohl eher gering. Zumal du auch keinen Code gezeigt hast - deshalb war anzunehmen, dass du es nicht in einem minimal Beispiel getestet hast und Schritt für Schritt den ursprünglichen Code wieder zusammengebaut hast.
Und das alles lässt darauf schließen, dass es dein Fehler war und nicht der vom GCC.
-
Shade Of Mine schrieb:
itman schrieb:
Du meinst das GCC im Prinzip keine Fehler hat, oder das sie sind nicht so einfach? z.B. Kern von Linux wird nur mit GCC version 3.x korrekt kompiliert
Jo, GCC ist ziemlich Fehlerfrei - natürlich nicht ganz, aber die wahrscheinlichkeit dass du einen Bug findest ist wohl eher gering. Zumal du auch keinen Code gezeigt hast - deshalb war anzunehmen, dass du es nicht in einem minimal Beispiel getestet hast und Schritt für Schritt den ursprünglichen Code wieder zusammengebaut hast.
Und das alles lässt darauf schließen, dass es dein Fehler war und nicht der vom GCC.
Jeder Feheler im Program ist der vorletzte Fehler