Forum: Compiler & IDEs Struct-Typ in Struct-Typ ergibt undefined reference


von Bronco (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein etwas seltsames Konstrukt gebastelt und bin damit auf die 
Nase gefallen. Und zwar hab ich in einem C++-Projekt einen Struct-Typ 
definiert, der einen weiteren Struct-Typ enthält. Den inneren Struct-Typ 
wollte ich dann als Datentyp verwendet.
Beispiel:
1
typedef struct {
2
  typedef struct { int member; } innen_t;
3
} aussen_t;
4
5
void TuEtwas( aussen_t::innen_t* innen_p ) { cout << innen_p->member; }
6
7
main()
8
{
9
  aussen_t::innen_t Innen;
10
  TuEtwas(&Innen);
11
}

Wenn ich dies in einer Datei mache, funktioniert es.
Wenn ich die Funktion "TuEtwas()" in ein eigenes C++-Modul packe, 
bekomme ich einen "undefined reference"-Fehler auf TuEtwas().
Wenn ich mir die Symbole des erzeugten ELF-Files ansehe, dann fehlt die 
Funktion "TuEtwas()" tatsächlich.

Mach ich da etwas undefiniertes oder verbotenes?

von Dr. Sommer (Gast)


Lesenswert?

Das typedef-Zeug kannst du dir in C++ sparen:
1
struct aussen_t {
2
  struct innen_t {
3
    int member;
4
  };
5
};
Der Fehler ist ganz einfach, dass du das andere "C++ Modul" (ich denke 
mal damit meinst du eine eigene Datei) nicht mit kompiliert&gelinkt 
hast. Dann wird beim Linken die Funktion nicht gefunden.

seltsam ist an den Konstrukt gar nichts, das ist einfach eine nested 
class. (class und struct ist in C++ dasselbe, bis darauf dass in struct 
alles per default public ist).

von Bronco (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Der Fehler ist ganz einfach, dass du das andere "C++ Modul" (ich denke
> mal damit meinst du eine eigene Datei) nicht mit kompiliert&gelinkt
> hast. Dann wird beim Linken die Funktion nicht gefunden.
Doch, das hab ich!

Der Hintergrund ist folgender:
Ich hab in C++ eine Library geschrieben, die als "shared object" in 
einem Embedded Linux-System eingesetzt wird.
Intern arbeitet die Library mit Klassen, aber die Schnittstellen nach 
außen hab ich mit C-Funktionen und C-Structs aufgebaut.

Als ich die Library dann in einem anderen Projekt verwenden wollte, 
waren ganz genau all die Funktionen nicht vorhanden, die als Parameter 
einen "inneren Struct-Typ" haben.

Auch interessant:
Ich habe auch Struct-Typen, die Enum-Typen enthalten. Die Funktionen mit 
einem "inneren Enum-Typ" sind alle vorhanden.

Ich hab eher das Gefühl, dass der Compiler (Mucross GCC 4.9.0) Probleme 
hat, diese Datentypen darzustellen...?

von Dr. Sommer (Gast)


Lesenswert?

Bronco schrieb:
> Intern arbeitet die Library mit Klassen, aber die Schnittstellen nach
> außen hab ich mit C-Funktionen und C-Structs aufgebaut.
Solche "C-Funktionen" können aber kein "inneres" struct als Parameter 
haben, denn verschachtelte structs gibts in C nicht.

Gibt's einen Grund warum die deine Schnittstelle nicht einfach als C++ 
ausführst und den Umweg über C gehst?

von Bronco (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Bronco schrieb:
>> Intern arbeitet die Library mit Klassen, aber die Schnittstellen nach
>> außen hab ich mit C-Funktionen und C-Structs aufgebaut.
> Solche "C-Funktionen" können aber kein "inneres" struct als Parameter
> haben, denn verschachtelte structs gibts in C nicht.
Okay, das wußt ich nicht!
Das Verhalten ist aber trotzdem seltsam...

> Gibt's einen Grund warum die deine Schnittstelle nicht einfach als C++
> ausführst und den Umweg über C gehst?
Ja, ich hab bisher noch nie ein shared object gemacht und dachte, das 
wäre eine gute Idee ;)
Aber ich werde das nochmal gründlich überdenken!

von Dr. Sommer (Gast)


Lesenswert?

Bronco schrieb:
> Okay, das wußt ich nicht!
> Das Verhalten ist aber trotzdem seltsam...
Ja, schon. Du hast vermutlich extern "C" an den Funktionen? Kompiliert & 
Gelinkt mit "g++"? Dann sollten sie auf jeden Fall im ELF sein. Das der 
C Compiler sie nicht findet ist eine andere Sache.
> Ja, ich hab bisher noch nie ein shared object gemacht und dachte, das
> wäre eine gute Idee ;)
Nur wenn man von anderen Sprachen als C++ drauf zugreifen will...

von Bronco (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Bronco schrieb:
>> Okay, das wußt ich nicht!
>> Das Verhalten ist aber trotzdem seltsam...
> Ja, schon. Du hast vermutlich extern "C" an den Funktionen? Kompiliert &
> Gelinkt mit "g++"? Dann sollten sie auf jeden Fall im ELF sein. Das der
> C Compiler sie nicht findet ist eine andere Sache.
Das ist ja das seltsame: Beim Compilieren und Linken der Library gibt es 
keine Fehlermeldung, aber wenn ich mir die Schnittstellen des shared 
objects mit "nm" anschaue, sind die besagten Funktionen einfach nicht 
da!
Erst wenn ich die Library einbinde, kommt beim Linken des einbindenden 
Projekts die "undefined reference"-Fehlermeldung.

>> Ja, ich hab bisher noch nie ein shared object gemacht und dachte, das
>> wäre eine gute Idee ;)
> Nur wenn man von anderen Sprachen als C++ drauf zugreifen will...
Was in meinem Fall noch nicht geklärt ist, weil ich diesen Teil nicht 
selbst machen werde.

von Dr. Sommer (Gast)


Lesenswert?

Bronco schrieb:
> aber wenn ich mir die Schnittstellen des shared
> objects mit "nm" anschaue, sind die besagten Funktionen einfach nicht
> da!
Bei mir funktionierts. Zeig mal den kompletten Code inkl. makefile.

von Bronco (Gast)


Lesenswert?

Ich hab jetzt anstatt "typedef structs" "class" verwendet - und jetzt 
geht's auch!
Verrückt... wahrscheinlich saß da der Fehler doch irgendwo vor dem 
Bildschirm...

Danke für Deine Hilfe!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
>  denn verschachtelte structs gibts in C nicht.

Natürlich gibt es in C "verschachtelte" structs; was magst Du meinen?

von Dr. Sommer (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> was magst Du meinen?
Das worum es die ganze Zeit geht:
1
struct A {
2
  struct B {
3
    int x;
4
  } b;
5
  int y;
6
};
7
8
void test (struct A::B* b) {
9
}
Zumindest mein GCC mag das nicht. Die struct-Definition im anderen 
struct geht zwar, aber ist dann nicht im Scope von A (d.h. A::B gibts 
nicht). Den Scope Resolution Operator gibts nicht in C

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> Den Scope Resolution Operator gibts nicht in C

Das stimmt; aber daß Du darauf abzielst, erschließt sich nicht aus der 
Formulierung "verschachtelte structs".

In so einem Fall muss man halt drauf verzichten. Ist das so schlimm?

von Dr. Sommer (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Dr. Sommer schrieb:
>> Den Scope Resolution Operator gibts nicht in C
>
> Das stimmt; aber daß Du darauf abzielst, erschließt sich nicht aus der
> Formulierung "verschachtelte structs".
Es ist halt kein wirklich verschachteltes struct, sondern nur eine 
verschachtelte Deklaration.
>
> In so einem Fall muss man halt drauf verzichten.
Ja. Soweit waren wir schon.
> Ist das so schlimm?
Vielleicht, vielleicht nicht. Darum ging es überhaupt nicht.

von Bronco (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Ist das so schlimm?

Wenn man es weiß, ist es nicht schlimm.
Wenn man es nicht weiß, muß man halt erstmal fragen... ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.