Dies ist eine statische Kopie unseres alten Forums. Es sind keine Interaktionen möglich.
This is a static copy of our old forum. Interactions are not possible.

migu

free rider

  • "migu" is male
  • "migu" started this thread

Posts: 2,643

Date of registration: Dec 11th 2001

Occupation: Developer

1

Friday, May 9th 2003, 7:11pm

GDV-Kurs: Linker

Beim Linken dieses Codes

#include "Solid.h"
int main(int argc, char **argv) {
Solid s;
return 0;
}

meldet der Linker:

/tmp/ccfixW67.o(.text+0x18 ): In function `main':
: undefined reference to `Solid::Solid[in-charge]()'
/tmp/ccfixW67.o(.text+0x27): In function `main':
: undefined reference to `Solid::~Solid [in-charge]()'
collect2: ld returned 1 exit status

Offenbar wird der Objekt-Code für den verantwortlichen Konstruktor nicht gefunden. Doch ich verstehe das Problem nicht ganz.
Solid.cc habe ich mit "g++ -c Solid.cc" übersetzt, ebenso Triangle.cc, die von Solid.cc gebraucht wird.

Schreibe ich statt
Solid s;
Solid s();
wird der Code gelinkt. Das kann doch nicht sein!
Dieser subtile Unterschied!
Mein anderer Konstruktor Solid(int) kann auch nicht gelinkt werden. Ein Destruktor ist vorhanden.
Seltsamerweise werden offenbar weder der Konstruktor, noch der Destruktor aufgerufen - bei Solid s();
Ich verstehe nicht mehr, was da los ist.

Sicherlich rufe ich g++ vollkommen falsch auf. hm...
tar: Anlegen eines leeren Archivs wird feige verweigert.

np

Junior Schreiberling

Posts: 155

Date of registration: Oct 23rd 2002

2

Monday, May 12th 2003, 8:56am

Mit welchem Befehl linkst Du denn?

Der Unterschied zwischen:

Solid s;

und

Solid s();

ist übrigens folgender:

Solid s; konstruiert ein Objekt s vom Typ Solid mittels default-Konstruktor Solid::Solid() (das ist es, was Du willst).

Solid s(); deklariert eine (leere) Funktion ::s() ohne Parameter mit Rückgabetyp Solid (das willst Du sicher nicht). Dies erklärt, warum Version II linkt, aber nicht tut, was sie soll.
Der historische Grund für dieses seltsame Verhalten ist, dass früher void-Funktionen als Solid s(void); deklariert werden mussten. Weil das gewissen Leuten (und Java-Programmierern) zuviel zu tippen war, musste die (logische aber selten gebrauchte) Konstruktor-Variante Solid s(); dran glauben.

migu

free rider

  • "migu" is male
  • "migu" started this thread

Posts: 2,643

Date of registration: Dec 11th 2001

Occupation: Developer

3

Wednesday, May 14th 2003, 3:53pm

Quoted

Original von np
Mit welchem Befehl linkst Du denn?


g++ linkt für mich direkt nach dem Kompilieren:

g++ -o main main.o Triangle.o Solid.o

(nachdem ich zuvor jede *.cc mit g++ -c <cc-file> kompilierte)

Inzwischen schlägt das Linken auch dann fehl, wenn ich

Solid s;

schreibe. :( ?(
Es sind aber inzwischen andere Fehler. Am Konstruktor von Solid liegt es nicht mehr.
Ich habe den Fehler gefunden. Es ist denkbar blöde und einfach - jetzt wo ich es weiß.
Ich vergaß doch tatsächlich, Vector3d.cc zu übersetzen.
Es muss also heißen:

g++ -o main main.o Triangle.o Solid.o Vector3d.o

:) :) :D

Daraus ziehe ich die Lehre, ein Makefile zu schreiben. ;)

Quoted


Solid s; konstruiert ein Objekt s vom Typ Solid mittels default-Konstruktor Solid::Solid() (das ist es, was Du willst).

Solid s(); deklariert eine (leere) Funktion ::s() ohne Parameter mit Rückgabetyp Solid (das willst Du sicher nicht). Dies erklärt, warum Version II linkt, aber nicht tut, was sie soll.
Der historische Grund für dieses seltsame Verhalten ist, dass früher void-Funktionen als Solid s(void); deklariert werden mussten. Weil das gewissen Leuten (und Java-Programmierern) zuviel zu tippen war, musste die (logische aber selten gebrauchte) Konstruktor-Variante Solid s(); dran glauben.


Aha, das ist interessant. Danke für die Hilfe. :)

Geschachtelte Funktionen sind in C++ aber verboten. Also kann

Solid s();

innerhalb von main() keine Funktion deklarieren.
Dazu Bjarne Stroustrup in seinem Standardwerk (Anhang A.7):
"Die Grammatik erlaubt das beliebige Schachteln von Deklarationen. Es gibt allerdings einige semantische Einschränkungen. Geschachtelte Funktionen (Funktionen, die lokal in anderen Funktionen definiert werden) sind z.B. nicht erlaubt."

Und tatsächlich kompiliert die Variante mit

Solid s();

ohne Probleme.

Jetzt kann's also richtig losgeh'n! :) :)
tar: Anlegen eines leeren Archivs wird feige verweigert.