amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > C++ von GCC 2.95.3 nach GCC 3.3 portieren [ - Suche - Neue Beiträge - Registrieren - Login - ]

1 -2- 3 [ - Beitrag schreiben - ]

12.05.2007, 13:01 Uhr

Holger
Posts: 8090
Nutzer
Zitat:
Original von gni:
FWIW, kein Fehler mit allen von mir getesten GCC Versionen (2.95.x, 3.3.6, 3.4.6, 4.0.0, 4.1.0)

Was wiederum zu dem Schluss führt, dass es sich um andere includes handelt. Da die Wahrscheinlichkeit, dass die Definition von HOOKFUNC, die nur sechs Zeilen von der Definition von Hook entfernt ist, von selbiger abweicht, sehr gering ist, würde ich mal darauf tippen, dass bei Reth HOOKFUNC irgendwo anders (um)definiert wird. Das müsste dann zwar ein ziemlich verkorkstes setup sein, aber möglich wäre es.

Es gibt ja Versionen von hooks.h, in denen gar kein HOOKFUNC definiert wird. Wenn es dann anderweitig definiert wird, würde ein compiler nicht meckern. Erst bei der inkompatiblen Zuweisen von HOOKFUNC nach h_[Sub]Entry.

Ich weiß schon, warum ich C so liebe :D

mfg

PS: Sind Deine Testumgebungen auch, wie bei Reth, die von der GoldEd Installation oder andere?
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

12.05.2007, 15:41 Uhr

Reth
Posts: 1812
Nutzer
Hallo nochmals und vielen Dank für eure Beteiligung!

Zitat:
Original von Holger:
Zitat:
Original von gni:
FWIW, kein Fehler mit allen von mir getesten GCC Versionen (2.95.x, 3.3.6, 3.4.6, 4.0.0, 4.1.0)

Was wiederum zu dem Schluss führt, dass es sich um andere includes handelt. Da die Wahrscheinlichkeit, dass die Definition von HOOKFUNC, die nur sechs Zeilen von der Definition von Hook entfernt ist, von selbiger abweicht, sehr gering ist, würde ich mal darauf tippen, dass bei Reth HOOKFUNC irgendwo anders (um)definiert wird. Das müsste dann zwar ein ziemlich verkorkstes setup sein, aber möglich wäre es.

Es gibt ja Versionen von hooks.h, in denen gar kein HOOKFUNC definiert wird. Wenn es dann anderweitig definiert wird, würde ein compiler nicht meckern. Erst bei der inkompatiblen Zuweisen von HOOKFUNC nach h_[Sub]Entry.

Ich weiß schon, warum ich C so liebe :D

mfg


Werde vllt. mal Dietmar Eilert fragen, wo ich genau nachsehen kann, welche Includes der Compiler hier anzieht. Oder kann ich mir das via make-Parameter irgendwie ausgeben lassen?
Schaue bei Gelegenheit auch nochmal in alle installierten OS-Includes (3.x und 4), bzw. lass mir mal alles suchen, wo HOOKFUNC drin vorkommt und berichte dann (kann aber ne Weile dauern)!

Ciao

[ - Antworten - Zitieren - Direktlink - ]

12.05.2007, 19:57 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Holger:
Sind Deine Testumgebungen auch, wie bei Reth, die von der GoldEd Installation oder andere?

Kein GoldED. Getestet habe ich mit Cross-Compilern, aber meine GCC Installtion unter AmigaOS ist prinzipiell die gleiche bezüglich Compiler und Includes.

[ - Antworten - Zitieren - Direktlink - ]

12.05.2007, 19:58 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Reth:
Schaue bei Gelegenheit auch nochmal in alle installierten OS-Includes (3.x und 4), bzw. lass mir mal alles suchen, wo HOOKFUNC drin vorkommt und berichte dann (kann aber ne Weile dauern)!

Die Option -H zeigt Dir welche Includes benutzt werden.

[ - Antworten - Zitieren - Direktlink - ]

14.05.2007, 23:10 Uhr

Reth
Posts: 1812
Nutzer
Also hab mal meine Suche auf hooks.h eingegrenzt und bei mir sind die Sachen in der GoldED-Installation überall (inkl. NDK3.9 und SDK4.0, mit Ausnahme des MOS-SDK (welches ich nicht nehme) wie folgt definiert:
C++ code:
struct Hook
{
    struct MinNode h_MinNode;
    ULONG    (*h_Entry)(); /* assembler entry point */
    ULONG    (*h_SubEntry)(); /* often HLL entry point */
    APTR    h_Data; /* owner specific  */
};

/* Useful definition for casting function pointers:
 * hook.h_SubEntry = (HOOKFUNC)AFunction
 */
typedef unsigned long (*HOOKFUNC)();


Der einzige Unterschied bei MOS ist, dass VOID angegeben ist, statt leerer Funktionsparameter!

Die Option -H (Danke gni!) zeigt mir, dass die includes aus .../gg/... genommen werden (die Anzahl der führenden Punkte variiert).
Wenn meine Assigns zu diesem Zeitpunkt nicht lügen, zeigt gg: zu dem Verzeichnis der GCC3.3-Installation mitsamt der Header für das OS3.x.

Ich hätte aber noch 2 weitere Fragen:

Unter 2.95.3 konnte ich mühelos die strlen-Funktion aus C auf ein char* anwenden (ohne was zu includieren). Der 3.3 kennt das nicht.
Muss ich hier irgend nen Standard-C-Header inkludieren, oder kann ich die Funktion gar nicht mehr verwenden und muss das Ganze über C++-Strings handhaben?

Das nächste wäre die Behandlung von Default-Argumenten in Methoden:
In meinen Büchern und im Web hab ich nix gefunden (oder aber ich habs immer übersehen?), das besagt, dass die Default-Argumente nur bei der Deklaration angegeben werden dürfen, nicht aber bei der Definition (hoffe, ich bring hier nicht wieder was durcheinander, will sagen, in den Header-Files der C++-Klassen kann ich Default-Argumente angeben, in den implementierenden Files bekomm ich vom 3.3er auf die Finger, wenn ichs dort genauso mache! Find ich an sich schade, da sich so die Methodensignaturen unterscheiden - für das Auge des Betrachters!)!?
Woran liegt das denn - will sagen, an welcher Klausel des Standards?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

15.05.2007, 09:52 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Reth:
Unter 2.95.3 konnte ich mühelos die strlen-Funktion aus C auf ein char* anwenden (ohne was zu includieren). Der 3.3 kennt das nicht.

Sei froh das 3.3 das Benutzen von Funktionen ohne Prototype anmeckert. Du mußt _immer_ den entsprechenden Header für eine Funktion einbinden.
Zitat:
Muss ich hier irgend nen Standard-C-Header inkludieren, oder kann ich die Funktion gar nicht mehr verwenden und muss das Ganze über C++-Strings handhaben?
Dir fehlt nur "#include <string.h>".
Zitat:
In meinen Büchern und im Web hab ich nix gefunden (oder aber ich habs immer übersehen?), das besagt, dass die Default-Argumente nur bei der Deklaration angegeben werden dürfen, nicht aber bei der Definition
Defaultargumente sind nur in der Class-Definition zulässig. Neuere GCC Versionen halten sich in vielen Fällen strikter an Standards und finden mehr Probleme. Du solltest darüber nachdenken, auch bei GCC2 mit -W -Wall zu übersetzen. Auch da sollten dann etwaige Probleme bereits diagnostiziert werden.
Zitat:
Woran liegt das denn - will sagen, an welcher Klausel des Standards?
Wo das im Standard steht, kann ich Dir auch nicht sagen. Nimms einfach hin ;-)

[ - Antworten - Zitieren - Direktlink - ]

15.05.2007, 17:12 Uhr

Holger
Posts: 8090
Nutzer
Zitat:
Original von gni:
Sei froh das 3.3 das Benutzen von Funktionen ohne Prototype anmeckert. Du mußt _immer_ den entsprechenden Header für eine Funktion einbinden.

Dem kann ich mich nur anschließen.
Zitat:
Dir fehlt nur "#include <string.h>".
Bzw., wie es für C++ empfohlen wird, #include <cstring>

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

15.05.2007, 21:13 Uhr

Reth
Posts: 1812
Nutzer
@gni:
Zitat:
Original von gni:
Und noch was: <slist> gibt es sehr wohl auch bei GCC3!

Bei:
C++ code:
#include <slist>

Bekomme ich aber gesagt:
code:
slist: No such file or directory




@Holger:
Zitat:
Original von Holger:
Bzw., wie es für C++ empfohlen wird, #include <cstring>


Hm bei mir hat hier wohl ein:
C++ code:
#include <string>

gelangt!?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

16.05.2007, 08:17 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Reth:
Bei:
C++ code:
#include <slist>

Bekomme ich aber gesagt:
code:
slist: No such file or directory


Versuchs mal mit <slist.h> oder dann mit <ext/slist>. Wenn Du Deinen Code mit beiden Compilerversionen übersetzen willst, kommst Du vermutlich um Fallunterscheidungen mittels "__GNUG__ > 2" wohl nicht rum.
Zitat:
Zitat:
Holger:
Bzw., wie es für C++ empfohlen wird, #include <cstring>

Hm bei mir hat hier wohl ein:
C++ code:
#include <string>

gelangt!?
Die Frage hätte Dir -H beantwortet. Kurz gesagt, das ist vermutlich ein Seiteneffekt, da <string> zum Einbinden von <cstring> führt. Ob das immer so sein muß, weis ich nicht. Wenn Du nur die die Prototypen für die C-Stringfunktionen benötigst, dann solltest Du wie Holger treffend anmerkte <cstring> einbinden.

[ - Antworten - Zitieren - Direktlink - ]

16.05.2007, 09:48 Uhr

Reth
Posts: 1812
Nutzer
Hallo gni!

Zitat:
Original von gni:
Versuchs mal mit <slist.h> oder dann mit <ext/slist>. Wenn Du Deinen Code mit beiden Compilerversionen übersetzen willst, kommst Du vermutlich um Fallunterscheidungen mittels "__GNUG__ > 2" wohl nicht rum.

Danke! Wollte aber eh auf dem 3.3er bleiben, wenn ichs mal migriert habe!
Liegt der andere Include-Ort von slist daran, dass es nicht in den Standard übernommen wurde?

Zitat:
Die Frage hätte Dir -H beantwortet. Kurz gesagt, das ist vermutlich ein Seiteneffekt, da <string> zum Einbinden von <cstring> führt. Ob das immer so sein muß, weis ich nicht. Wenn Du nur die die Prototypen für die C-Stringfunktionen benötigst, dann solltest Du wie Holger treffend anmerkte <cstring> einbinden.

Brauche in dieser Klasse Funktionen aus beiden Includes, werde daher wohl auch beide einbinden, also <string> und <cstring>, um sicher zu gehen, dass es überall klappt.

Ciao

[ - Antworten - Zitieren - Direktlink - ]

16.05.2007, 22:10 Uhr

Reth
Posts: 1812
Nutzer
Zitat:
Original von gni:
Versuchs mal mit <slist.h> oder dann mit <ext/slist>.


Also <slist.h> liefert ne deprecated Warnung, <ext/slist> tut, also fast, denn nun bekomm ich die Meldung:

error: 'slist' is used as a type, but is not defined as a type

wenn ich Variablen als slist-Typen deklariere wie z.B.:
C++ code:
slist<struct TagItem> tagItems;


Wie bekomm ich denn den Namespace raus, der hier verwendet werden muss?
std ists ja nicht, ist es ext?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

17.05.2007, 21:35 Uhr

Reth
Posts: 1812
Nutzer
Ok, der Namespace für slist ist: __gnu_cxx

Hab im Include geschaut und den ersten einfach probiert!

[ - Antworten - Zitieren - Direktlink - ]

24.05.2007, 00:09 Uhr

Reth
Posts: 1812
Nutzer
So nun kam das Unvermeidliche:

Nachdem alles angepasst wurde, so dass der GCC 3.3 durchkompiliert, kommen nun die Linkerfehler (mit denen ich noch nie was anfangen konnte! Gibts dazu irgendwo ne hilfreiche Doku oder so?):

code:
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/ncrt0.o(.text+0x60): undefined reference to 'main'
o/gcc-classic/AnimObjectManagerC.o(.text+0x16): undefined reference to '_ZN18AnimObjectManagerC10allObjectsE'
o/gcc-classic/AnimObjectManagerC.o(.text+0x28): undefined reference to '_ZN18AnimObjectManagerC10allObjectsE'
o/gcc-classic/AnimObjectManagerC.o(.text+0x118): undefined reference to '_ZN18AnimObjectManagerC10allObjectsE'
o/gcc-classic/AnimObjectManagerC.o(.text+0x12c): undefined reference to '_ZN18AnimObjectManagerC10allObjectsE'
o/gcc-classic/AnimObjectManagerC.o(.text+0x13e): undefined reference to '_ZN18AnimObjectManagerC10allObjectsE'
o/gcc-classic/AnimObjectManagerC.o(.text+0x22e): more undefined references to '_ZN18AnimObjectManagerC10allObjectsE' follow
o/gcc-classic/WizardGroundsC.o(.text+0xe62): undefined reference to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'
o/gcc-classic/WizardGroundsC.o(.text+0xe94): undefined reference to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'
o/gcc-classic/WizardGroundsC.o(.text+0xec6): undefined reference to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'
o/gcc-classic/WizardGroundsC.o(.text+0xef8): undefined reference to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'
o/gcc-classic/WizardGroundsC.o(.text+0xf2a): undefined reference to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'
o/gcc-classic/WizardGroundsC.o(.text+0xf5a): more undefined references to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap' follow
o/gcc-classic/WizardGroundsC.o(.text+0x1256): undefined reference to '_ZN13FrameFactoryC9getFramesEi'
o/gcc-classic/WizardGroundsC.o(.text+0x1282): undefined reference to '_ZN13FrameFactoryC9getFramesEi'
o/gcc-classic/WizardGroundsC.o(.text+0x17ec): undefined reference to '_ZN13FrameFactoryC9getFramesEi'
o/gcc-classic/WizardGroundsC.o(.text+0x1844): undefined reference to '_ZN13FrameFactoryC9getFramesEi'
o/gcc-classic/WizardGroundsC.o(.text+0x189e): undefined reference to '_ZN13FrameFactoryC9getFramesEi'
o/gcc-classic/WizardGroundsC.o(.text+0x18f8): more undefined references to '_ZN13FrameFactoryC9getFramesEi' follow
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libstdc++.a(basic_file.o)(.text+0x286): undefined reference to 'getc'
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libstdc++.a(basic_file.o)(.text+0x242): undefined reference to 'fdopen'
collect2: ld returned 1 exit status


AnimObjectManger und FrameFactory sind statische Klassen von mir, die anderen Fehler sind wohl auf irgendwelche Includes zurückzuführen.

allObjects sind im AnimObjectManger als private deklariert:
C++ code:
static std::map<const int, std::vector<AnimObjectC *> > allObjects;

createAddFrame sieht im FrameManger wie folgt aus:
C++ code:
static void createAddFrame(const int type, int width, int height, PLANEPTR data, PLANEPTR mask=NULL, const struct BitMap * const friendBitMap=NULL);


Bei Bedarf kann ich auch noch mehr Code posten (z.B. verwendende Stellen, die Implementierungen an sich und was noch gewünscht ist)!

Kann mir hier bitte jmd. weiterhelfen, da ich aus den Fehlermeldungen absolut nicht schlau werde!

Vielen Dank schon einmal!

Ciao

[ - Antworten - Zitieren - Direktlink - ]

24.05.2007, 09:14 Uhr

Solar
Posts: 3674
Nutzer
Zitat:
Original von Reth:

code:
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libnix/ncrt0.o(.text+0x60): undefined reference to 'main'



ncrt0.o ist die C Runtime, d.h. der Startup-Code, der die notwendingen Vorbereitungen trifft, bevor Deine int main() aufgerufen wird - ja, und genau diese int main() wird nicht gefunden.

Wenn's eine Library werden soll, mußt Du einen anderen Linkerbefehl verwenden, damit eben dieser Startup-Code nicht mit eingebunden wird.

Zitat:
code:
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libstdc++.a(basic_file.o)(.text+0x286): undefined reference to 'getc'
/gg/lib/gcc-lib/m68k-amigaos/3.3/../../../libstdc++.a(basic_file.o)(.text+0x242): undefined reference to 'fdopen'
collect2: ld returned 1 exit status



Die C++-Standardbibliothek versucht hier, C-Standard-Dateifunktionen einzubinden, die dann nicht gefunden werden... auch hier vermute ich einen fehlerhaften Linker-Aufruf.

Kannst Du Deine Compiler- und Linker-Kommandozeilen mal posten?


[ Dieser Beitrag wurde von Solar am 24.05.2007 um 09:14 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

24.05.2007, 09:35 Uhr

Reth
Posts: 1812
Nutzer
@Solar:

Danke für die Tips!

Werde versuchen heute Abend mal mein makefile zu posten.

Gibt es denn irgendwo aussagekräftige Beschreibungen zu diesen Linkerfehlern?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

24.05.2007, 12:43 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Solar:
Zitat:
Reth:
code:
.../libstdc++.a(basic_file.o): undefined reference to 'getc'
.../libstdc++.a(basic_file.o): undefined reference to 'fdopen'


Die C++-Standardbibliothek versucht hier, C-Standard-Dateifunktionen einzubinden, die dann nicht gefunden werden... auch hier vermute ich einen fehlerhaften Linker-Aufruf.
In dem Fall wohl nicht. libnix fehlen einige stdio-Funktionen, u.a. auch getc(). Diese Funktionen sind als Makro in stdio.h vorhanden, müssen aber auch als echte Funktionen existieren. Bei fdopen liegt der Fall etwas anders. Es kann sein, das die von reth verwendete Version kein fdopen() hat. Da kann man nicht viel machen. Die fehlenden stdio-Funktionen können "nachgerüstet" werden, siehe dazu hier. Für fdopen() braucht es wohl eine neue(re) libnix Version, denke ich mal.

[ - Antworten - Zitieren - Direktlink - ]

24.05.2007, 21:09 Uhr

Reth
Posts: 1812
Nutzer
Vielen Dank für eure Tips!

Hier mal ein Compileraufrufbsp. der Aufruf zum Linken (makefile macht wohl weniger Sinn, ist eh eins von GoldED, das dann nicht die Compilerparameter direkt enthält!).
Was bei mir auch noch der Fall ist: Nicht alle Klassen des Projektes sind im makefile drinne und es klappte unter 2.95.3 dennoch immer!
Z.B. fehlt die statische Klasse FrameFactory komplett, liegts evtl. daran?

Das mit dem fehlenden Main hab ich inzwischen lokalisiert! Ist noch ein fehlender Teil der Umstrukturierung, es gibt wirklich noch kein main()!

Eine weitere Frage nochmal: Wie erkenne ich denn nun aus den Linkerfehlern, was ihm fehlt!?

Compilerbsp.:

g++ -noixemul -c -o o/gcc-classic/GadgetMessageReceiverC.o GadgetMessageReceiverC.cc


Linken:

g++ o/gcc-classic/ScreenModeRequestC.o o/gcc-classic/ScreenModeHookC.o o/gcc-classic/ResourceC.o o/gcc-classic/GadgetC.o o/gcc-classic/ImageButtonC.o o/gcc-classic/PointC.o o/gcc-classic/HexManagerC.o o/gcc-classic/PlayerC.o o/gcc-classic/PlayerManagerC.o o/gcc-classic/HexagonC.o o/gcc-classic/FrameC.o o/gcc-classic/EdgeC.o o/gcc-classic/BuildingC.o o/gcc-classic/AnimObjectManagerC.o o/gcc-classic/AnimObjectC.o o/gcc-classic/AnimationC.o o/gcc-classic/MenuSeperatorC.o o/gcc-classic/MenusC.o o/gcc-classic/MenuC.o o/gcc-classic/MenuItemC.o o/gcc-classic/MenuEntryC.o o/gcc-classic/ScreenC.o o/gcc-classic/RastPortC.o o/gcc-classic/WindowC.o o/gcc-classic/WizardGroundsC.o o/gcc-classic/ActivityC.o o/gcc-classic/QuitActivityC.o o/gcc-classic/IntuiTickActivityC.o o/gcc-classic/ClickHandlerC.o o/gcc-classic/TowerGadgetActivityC.o o/gcc-classic/ApplicationC.o o/gcc-classic/GUIApplicationC.o o/gcc-classic/MessageC.o o/gcc-classic/IntuiMessageC.o o/gcc-classic/IntuiMessageReceiverC.o o/gcc-classic/MenuMessageReceiverC.o o/gcc-classic/GadgetMessageReceiverC.o -noixemul -o bin/gcc-classic/WizardWars

Ciao

[ - Antworten - Zitieren - Direktlink - ]

25.05.2007, 10:09 Uhr

Solar
Posts: 3674
Nutzer
Zitat:
Original von Reth:

Was bei mir auch noch der Fall ist: Nicht alle Klassen des Projektes sind im makefile drinne und es klappte unter 2.95.3 dennoch immer!
Z.B. fehlt die statische Klasse FrameFactory komplett, liegts evtl. daran?


*Hust*... wie soll er denn ein Objekt einbinden, von dem er nicht einmal weiß, daß es existiert?

Eventuell wurde bei Deiner 2.95.3-Installation das lokale Verzeichnis automatisch mit durchsucht beim Linken, aber Du solltest ihm schon explizit sagen, welchen Code Du gerne mit drinhättest. Automatisch eingebundene eigene Objektdateien können eine ganz fiese Fehlerquelle sein...

Zitat:
Eine weitere Frage nochmal: Wie erkenne ich denn nun aus den Linkerfehlern, was ihm fehlt!?

Wissen, wie eine Objektdatei aussieht und was beim Linken passiert. Dann kann man aus den Linkerfehlern schon schlau werden:

code:
o/gcc-classic/WizardGroundsC.o(.text+0xe94): undefined reference
to '_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap'


In der Objektdatei o/gcc-classic/WizardGroundsC.o, an Code-Offset 0xe94, wird auf das entsprechende Symbol mit externer Linkage bezug genommen - das kann ein globales Objekt sein, oder eine Funktion. Der Symbolname ist deshalb so kryptisch, weil bei C++ ja z.B. mehrere Funktionen mit demselben Namen existieren können - im Symbolnamen ist deshalb die Parameterliste mit reinkodiert. Rückgängig machen kann man das mit c++filt:

code:
$ echo "_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap" | c++filt
FrameFactoryC::createAddFrame(int, int, int, unsigned char*, unsigned char*, const BitMap*)



[ Dieser Beitrag wurde von Solar am 25.05.2007 um 10:10 Uhr geändert. ]

[ Dieser Beitrag wurde von Solar am 25.05.2007 um 10:15 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

25.05.2007, 12:31 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Solar:
Rückgängig machen kann man [kryptische Namen] mit c++filt

AFAIK, "moderne" Linker machen diese Dekodierung von sich aus. Mit der Option -C zu nm kann man eine Liste mit dekodierten Namen der Symbole eines Objektfiles bekommen.
Zitat:
code:
$ echo "_ZN13FrameFactoryC14createAddFrameEiiiPhS0_PK6BitMap" | c++filt


Das geht auch ohne echo .-)

[ - Antworten - Zitieren - Direktlink - ]

25.05.2007, 13:59 Uhr

Solar
Posts: 3674
Nutzer
Hängt vom c++filt ab... ich hatte hier nur das von Solaris, und das interpretiert Argumente als Dateinamen... I-)

[ - Antworten - Zitieren - Direktlink - ]

29.05.2007, 21:16 Uhr

Reth
Posts: 1812
Nutzer
Danke für den Tip mit filt!

Zitat:
Original von Solar:

*Hust*... wie soll er denn ein Objekt einbinden, von dem er nicht einmal weiß, daß es existiert?


Da fragst Du mich zuviel! :D
Der 2.95.3 hat jedenfalls alles gefunden, was er brauchte, auch wenn nicht alle Implementierungen und Header im Make angegeben waren und dementsprechend auch nicht alle Klassen als .o für das Linken aufgeführt waren.

Zitat:
Eventuell wurde bei Deiner 2.95.3-Installation das lokale Verzeichnis automatisch mit durchsucht beim Linken, aber Du solltest ihm schon explizit sagen, welchen Code Du gerne mit drinhättest. Automatisch eingebundene eigene Objektdateien können eine ganz fiese Fehlerquelle sein...

D.h. ich sollte alles, was ich im Exe ham will in ein Objectfile compilieren und alle Objektdateien dann beim Linken mit angeben, oder?
Spielt denn die Reihenfolge hier irgend eine Rolle (Compilierreihenfolge, Linkreihenfolge)?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

29.05.2007, 21:18 Uhr

Reth
Posts: 1812
Nutzer
Zitat:
Original von gni:
AFAIK, "moderne" Linker machen diese Dekodierung von sich aus. Mit der Option -C zu nm kann man eine Liste mit dekodierten Namen der Symbole eines Objektfiles bekommen.


Heisst das, ich kann beim entsprechenden Linkaufruf des g++ einfach den Parameter -C mitgeben (oder wie muss ich das nm verstehen)?

Ciao

[ - Antworten - Zitieren - Direktlink - ]

30.05.2007, 12:20 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Heisst das, ich kann beim entsprechenden Linkaufruf des g++ einfach den Parameter -C mitgeben (oder wie muss ich das nm verstehen)?
nm ist ein separates Tool, das Dir Sybolinformationen zu einem Objektfile gibt. Mit dem Linker hat das nichts zu tun. Eventuell funktioniert folgendes als Option beim Linken: -Wl,--demangle

[ - Antworten - Zitieren - Direktlink - ]

31.05.2007, 08:29 Uhr

Solar
Posts: 3674
Nutzer
Zitat:
Original von Reth:

Der 2.95.3 hat jedenfalls alles gefunden, was er brauchte, auch wenn nicht alle Implementierungen und Header im Make angegeben waren und dementsprechend auch nicht alle Klassen als .o für das Linken aufgeführt waren.


Jo... das ist dann ungefähr so wie HTML im Internet Explorer, oder Spiele für Kickstart 1.3: "Die neue Version ist blöd, auf der alten ging's noch." I-)

Zitat:
D.h. ich sollte alles, was ich im Exe ham will in ein Objectfile compilieren und alle Objektdateien dann beim Linken mit angeben, oder?

Üblicherweise compiliert man jede .c / .cpp-Datei in eine eigene Objektdatei, und linkt die dann zusammen, ja.

Zitat:
Spielt denn die Reihenfolge hier irgend eine Rolle (Compilierreihenfolge, Linkreihenfolge)?

Für den Alltagsgebrauch, nein.


[ - Antworten - Zitieren - Direktlink - ]

05.06.2007, 22:54 Uhr

Reth
Posts: 1812
Nutzer
@gni:
@solar:

Also wenn ich das hier in der Shell probiere unter AOS4 mit installiertem GoldED AIX und aktiviertem GCC3.3 (68k) probiere:
code:
echo "_ZN13FrameFactoryC6framesE" | c++filt


bekomme ich nur gesagt:
code:
_ZN13FrameFactoryC6framesE


Das hilft nicht wirklich. Und erst ein GCC-Studium und eines über Objektdateien und Linker möchte ich mir nicht antun, "nur" um ein wenig C/C++ zu programmieren!

Die Sachen sollen funktionieren und wenn es Fehler gibt sollten die in menschenverständlicher Form mitgeteilt werden!

Hat hierzu noch jmd. ne Idee?

Was stimmt denn mit den statischen Klassen nicht? Die FrameFactory ist nun auch brav mit im makefile.
Es wird allerdings nirgends ein Objekt davon angelegt (Methoden sind ja alle statisch) und auch das private Member (muss ich das noch explizit initialisieren, wenn ja wie? Ist ja private!).

Ich hab da keinen Plan mehr!

Werde heut Nachmittag/Abend mal den Code der FrameFactory und ein Bsp. ihrer Verwendung posten.
Vllt. kann mir jmd. sagen, was ich alles falsch mache!

Ciao

[ Dieser Beitrag wurde von Reth am 06.06.2007 um 08:14 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

06.06.2007, 15:22 Uhr

Holger
Posts: 8090
Nutzer
Zitat:
Original von Reth:
Was stimmt denn mit den statischen Klassen nicht? Die FrameFactory ist nun auch brav mit im makefile.
Es wird allerdings nirgends ein Objekt davon angelegt (Methoden sind ja alle statisch) und auch das private Member (muss ich das noch explizit initialisieren, wenn ja wie? Ist ja private!).

Hä?
Du kompilierst Code, der in den Methoden steht. Solange diese nicht als inline-Methoden deklariert sind, führt ein Übersetzen des Quellcodes zu Objektcode, ob das nun Funktionen, statische oder Member-Methoden sind, ob irgendwelche Objekte zur Laufzeit angelegt oder die Methoden jemals aufgerufen werden, spielt dabei überhaupt keine Rolle.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

06.06.2007, 15:41 Uhr

Reth
Posts: 1812
Nutzer
@Holger:

Wo ist dann das Problem des Linkers?

[ - Antworten - Zitieren - Direktlink - ]

06.06.2007, 16:56 Uhr

Holger
Posts: 8090
Nutzer
@Reth:
Ich kenn weder Deinen Code, noch Dein Makefile. Da zu spekulieren, ist etwas müßig. Du musst die Sourcen sowohl kompilieren (das .o file anlegen), als auch beim linken mit angeben. Ansonsten gibt es wahrscheinlich jede Menge Mittel und Wege, das Hinzufügen zum Objektfile wirksam zu verhindern, wenn man sich kreativ anstellt...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

06.06.2007, 22:57 Uhr

Reth
Posts: 1812
Nutzer
@Holger:

Naja, drum hier wie angedroht der Code:

Header:
C++ code:
#ifndef FRAMEFACTORY_H
#define FRAMEFACTORY_H

#include <map>
#include <iostream>
#include <vector>
#include <time.h>
#include "FrameC.h"

class FrameFactoryC
{
 public:
        static void createAddFrame(const int type, int width, int height, PLANEPTR data, PLANEPTR mask=NULL, const struct BitMap * const friendBitMap=NULL);
        static const std::vector<FrameC *> &getFrames(const int type);
  
 private:
        static std::map<const int, std::vector<FrameC *> > frames;  

        FrameFactoryC();
        ~FrameFactoryC();
        FrameFactoryC(const FrameFactoryC&);
        void operator=(const FrameFactoryC&);
};
#endif


Implementierung:
C++ code:
#include "FrameFactoryC.h"

FrameFactoryC::FrameFactoryC()
{
}

FrameFactoryC::~FrameFactoryC()
{
    for (std::map<const int, std::vector<FrameC *> >::iterator iter = frames.begin(); iter != frames.end(); iter++)
    {
        for (std::vector<FrameC *>::iterator itVec = iter->second.begin(); itVec != iter->second.end(); itVec++)
        {
            delete (*itVec);
        }        
        iter->second.clear();
    }
    frames.clear();
}

void FrameFactoryC::createAddFrame(const int type, int width, int height, PLANEPTR data, PLANEPTR mask, const struct BitMap * const friendBitMap)
{
    FrameC *frame = new FrameC(width, height, data, mask, friendBitMap);
    frames[type].push_back(frame);
}

const std::vector<FrameC *> &FrameFactoryC::getFrames(const int type)
{
    return frames[type];
}


Verwendung:
C++ code:
FrameFactoryC::createAddFrame(GFX_LAKEFIELD, HEXWIDTH, HEXHEIGHT, (PLANEPTR)lake_data, (PLANEPTR)mask_data, getWindow()->getBitMap());


Makefile:
code:
EXE    = bin/gcc-classic/WizardWars
OBJDIR = o/gcc-classic/

...


$(OBJDIR)FrameFactoryC.o : FrameFactoryC.cc
 g++ $(shell gccprefs) -c -o $(OBJDIR)FrameFactoryC.o FrameFactoryC.cc

...


OBJS = <lauter Objetkdateien> \
<noch mehr Objektdateien> \
$(OBJDIR)FrameFactoryC.o \
<und wieder Objektdateien>
...

$(EXE) : $(OBJS)
 g++ $(OBJS) $(shell gccprefs) -o $(EXE)


Die FrameFactory soll zur Laufzeit für die Erzeugung und Verwaltung von Frames zuständig sein und diese Frames beim Beenden des Programmes wieder löschen (weiss nur nicht, ob der Destruktor auch gerufen wird?).
Denke mal, die andere Klasse poste ich, wenn ich die Probleme hier gelöst bekommen habe.

Stört es den Linker vielleicht, dass ich die statische Membervariable im nicht-statischen Destruktor verwende?
Da müsste doch aber schon der Compiler meckern, oder nicht?

Es ist wahrscheinlich kürzer, wenn ihr mir sagen würdet, was alles richtig ist, aber das hilft leider nicht soviel! :D

Ich denke mal, dass dem Linker die Initialisierung der privaten Variable fehlt.
Muss ich das in der Implementierungsdatei so angeben:
C++ code:
FrameFactoryC::frames();

?

Ciao

[ Dieser Beitrag wurde von Reth am 07.06.2007 um 16:17 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.06.2007, 23:28 Uhr

Reth
Posts: 1812
Nutzer
Also ein:
C++ code:
std::map<const int, std::vector<FrameC *> > FrameFactoryC::frames;


brachte hier Abhilfe.

Der Linkerfehler war der einer undefined reference.
Hat deswegen c++filt versagt?

Oder kann mir jmd. sagen, wieso c++filt hier nicht funktioniert hat bzw., ob es bei der GoldED Installation überhaupt tut?

Ciao

[ - Antworten - Zitieren - Direktlink - ]


1 -2- 3 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > C++ von GCC 2.95.3 nach GCC 3.3 portieren [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2022 by amiga-news.de - alle Rechte vorbehalten.
.