Forum: Compiler & IDEs warum macht der Linker underscores vor die Namen?


von Walter S. (avatar)


Lesenswert?

ich versuche ein bestehendes C-Project unter xcode auf dem MAC zu bauen.
Der Compiler macht da aus irgendeinem Grund _ vor die Funktionsnamen und 
der Linker findet die dann nicht. Irgendwie hatte ich das schon Mal, es 
war irgendwas mit C und C++, habs aber vergessen wie man das umgeht.


Also in einem file der AUfruf
irgendwas(13);

in einem anderen File die Definition:
void irgendwas(int zahl) ...

und er Linker verlangt dann nach _irgendwas

von Bruno V. (bruno_v)


Lesenswert?

Kümmer Dich nicht um den _. Ist nur zur Vermeidung von gleichen Namen 
C/Assembler.

Dem linker fehlt das (compilierte) File oder die lib, die die Funktion 
enthält. In C ohne _, im Assembler/Linker mit _.

: Bearbeitet durch User
von Walter S. (avatar)


Lesenswert?

danke, ich probier morgen weiter

von Wilhelm M. (wimalopaan)


Lesenswert?

Walter S. schrieb:
> Also in einem file der AUfruf
> irgendwas(13);
>
> in einem anderen File die Definition:
> void irgendwas(int zahl) ...
>
> und er Linker verlangt dann nach _irgendwas

Willst Du von C++-Code aus bspw. C-Funktionen aufrufen? Dann hast Du es 
mit dem Name-Mangling des C++-Compilers zu tun. Das müsstest Du für die 
C-Funktionsdeklarationen mit
1
extern "C" {
2
    int CFunction(void);
3
}

ausschalten.

von Harald K. (kirnbichler)


Lesenswert?

Wenn der Linker solch einen Symbolnamen nicht findet, wird dem Linker 
nicht die Objektdatei übergeben, in der das Symbol definiert ist.

Oder das Symbol (hier: die Funktion "irgendwas") ist als static 
deklariert und ist daher nur innerhalb ihrer "translation unit" 
sichtbar.

Da der Linker _irgendwas sucht, wird diese Funktion auch nicht aus 
C++-Code heraus aufgerufen, denn deren Signatur sähe durch das "name 
mangling" entschieden anders aus.

Es könnte sein, daß die Funktion "irgendwas" aber als C++-Code übersetzt 
wurde, und daß der Aufrufer sie als C-Code aufrufen will, also genau 
andersherum als von Wilhelm beschrieben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das zusätzliche "leading underscore" in Symbolnamen wird von manchen 
ABIs vorgeschrieben, d.h. ein Symbolname hat 1 Underscore mehr als auf 
anderen Plattformen.

So wird ein Object (Funktion oder Variable), das auf C-Ebene sym heißt, 
im Assembly als _sym ausgegeben. Beispiel C:
1
int var;
2
3
int fun (void)
4
{
5
    return var;
6
}
wird assembliert mit x686-w64-mingw32-gcc (unbedeutende Teile entfernt):
1
  .globl  _fun
2
_fun:
3
  movl  _var, %eax
4
  ret
5
6
  .globl  _var
7
  .bss
8
_var:
9
  .space 4

Und das gilt dann auch für C++:

fun wird in MinGW als __Z3funv assembliert, für x86_64-linux-gnu 
hingegen als _Z3funv.

Was unter MinGW auffällt, ist dass Labels zum Beispiel "L5" heißen, was 
ohne Underscore dann mit einem Objekt namens "L5" verwechselt werden 
würde. Das ABI vermeidet dies, indem Symbole von Hochsprache einen "_" 
verpasst bekommen.

Auf anderen Plattformen werden Labels z.B. als ".L5" benamt; keine 
Ahnung warum das unter Windows nicht gemacht wird / wurde.  Evtl. kann 
ein Archäologe da mehr zu sagen.

------------------------------------------------------------

Um in einem Project C und C++ zusamme zu nutzen müssen die C-Teile als 
extern "C" Linkage implementiert sein, im obigen Beispiel etwa
1
extern "C" int fun (void);

Um Assembly und C/C++ zusammen zu verwenden, muss im Assembly die Naming 
Convention dem ABI folgen.  Es ist zwar möglich, den Assembly Name mit 
GCC anzugeben, aber dabei wird man nach Möglichkeit dem ABI folgen, hier 
als GCC Erweiterung:
1
int fun (void) __asm ("_bar");

Schließlich gibt es je nach Host noch -f[no-]leading-underscore, aber 
was ABI angeht gilt das eben gesagte.

von Walter S. (avatar)


Lesenswert?

Vielen Dank an alle,
bin leider erst jetzt wieder dazu gekommen,
gleich der erste Post von Bruno war's:
ich hatte ja ein Projekt von Linux auf MAC portiert und beim Erstellen 
in Xcode zwei von an die 30 Quell-Files übersehen und der Linker hat 
dann natürlich die fehlenden Funktionen bemängelt und mich mit den 
Underscores vor den Namen verwirrt, jetzt geht's

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.