Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Kein Name-Mangling für main()?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
22.05.2012, 13:02 Uhr
ao

(Operator)


Hallo zusammen,

schon hundertmal verwendet, aber noch nie drüber nachgedacht:

C++-Compiler verwenden Name-Mangling, um aus Namespace, Klassenname, Funktionsname und Parameterliste einen eindeutigen Symbolnamen zusammenzusetzen, mit dem der Linker hantieren kann. Deswegen kann es Funktionen gleichen Namens in verschiedenen Scopes geben und deswegen ist auch Funktionsüberladung möglich.

Um das Name-Mangling zu unterdrücken, schreibt man vor den Funktionskopf noch

C++:
extern "C"


So weit klar. Jetzt die Frage:

Warum kann ich in einem .cpp-File dies hier schreiben?

C++:
int main (int argc, char * argv []) // OHNE extern "C"!
{
    return 0;
}


Woher weiß der Compiler, dass er ein ungemangeltes Symbol _main erzeugen soll, das vom Linker aufgelöst und vom Startup-Code angesprungen werden kann? Magie?

Kann mich jemand aufklären?

Dieser Post wurde am 22.05.2012 um 13:04 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.05.2012, 13:50 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


ich würd mal vermuten: hard-coded

da:


C++:
int foo()
{
}

int main (int argc, char * argv []) // OHNE extern "C"!
{
    foo();
    return 0;
}



ergibt


asm:

    .file   "test.cpp"
    .text
.globl _Z3foov
    .type   _Z3foov, @function
_Z3foov: ;hier ist unser foo
.LFB0:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    leave
    ret
    .cfi_endproc
.LFE0:
    .size   _Z3foov, .-_Z3foov
.globl main
    .type   main, @function
main: ;und hier die main
.LFB1:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    call    _Z3foov
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE1:
    .size   main, .-main
    .ident  "GCC: (Debian 4.4.5-8) 4.4.5"
    .section    .note.GNU-stack,"",@progbits


--
class God : public ChuckNorris { };

Dieser Post wurde am 22.05.2012 um 13:51 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.05.2012, 14:18 Uhr
Hans
Library Walker
(Operator)


Hi,

Zitat von ao:

Woher weiß der Compiler, dass er ein ungemangeltes Symbol _main erzeugen soll, das vom Linker aufgelöst und vom Startup-Code angesprungen werden kann? Magie?


Soweit ich weis, ist es in C und C++ definiert, also im Srandard festgelegt, dass ein Programm mit der Funktion main() anzufangen hat, weshalb diese deshalb vom Startupcode aufgerufen wird. Darum muss es in einem lauffähigen Programm eine main-funktion geben, während sie in Modulen durchaus fehlen darf. Hat also nichts mit Magie zu tun.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.05.2012, 15:09 Uhr
ao

(Operator)



Zitat von FloSoft:


Code:
.globl _Z3foov
    .type   _Z3foov, @function
_Z3foov: ;hier ist unser foo

; ............

.globl main
    .type   main, @function
main: ;und hier die main



Das ist ja das Interessante: foo () wird gemangelt zu _Z3foov, main () wird nicht gemangelt, sondern bleibt 1:1 stehen und kriegt noch nicht mal den sonst üblichen Unterstrich.


Zitat von Hans:
Soweit ich weis, ist es in C und C++ definiert, also im Srandard festgelegt, dass ein Programm mit der Funktion main() anzufangen hat, weshalb diese deshalb vom Startupcode aufgerufen wird. Darum muss es in einem lauffähigen Programm eine main-funktion geben, während sie in Modulen durchaus fehlen darf. Hat also nichts mit Magie zu tun.


Dass der Name main im Standard festgelegt ist, weiß ich. Aber solche Festlegungen dienen ja nur dazu, dass man portablen Code schreiben kann, der von jedem C++-Compiler übersetzt wird. Dass main auf "magische" Weise anders kompiliert wird als andere Funktionsnamen, war mir neu.

Doch, es muss magisch sein. Ich hab hier einen Schnipsel aus dem Startupcode für meinen Microcontroller (ARM Cortex M3, gcc-Assembler):


Code:
// hier kann man den Namen der Hauptfunktion "überschreiben"
#ifndef APP_ENTRY_POINT
#define APP_ENTRY_POINT main
#endif

// Jetzt kommt ganz viel Startup-Kram:
// Stack klarmachen, Variablen initialisieren,
// BSS nullen, Heap einrichten, Konstruktoren aufrufen,
// und dann das hier:

  ldr r2, =APP_ENTRY_POINT   // Adresse von main laden
  blx r2                      // und anspringen.




Modifiziere ich das so:


Code:
#ifndef APP_ENTRY_POINT
#define APP_ENTRY_POINT haupt   // Haupt-Funktion heißt jetzt "haupt"
#endif



dann funktioniert das nur, wenn ich im Cpp-Code schreibe:


C++:
extern "C" int haupt ()  // hier muss extern "C" hin, sonst Linkerfehler.
{
    return 0;
}

Dieser Post wurde am 22.05.2012 um 15:11 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.05.2012, 00:15 Uhr
Hans
Library Walker
(Operator)


Hi,

ich muss mich korrigieren: es scheint davon abzuhängen, wie der Compiler implementiert ist. Das Beispiel von FloSoft sieht so aus, wenn es vom Open Watcom 1.9 übersetzt wurde:

Code:
.387
.386p
.model flat
        PUBLIC    `W?foo$n()i`
        PUBLIC    main_
        EXTRN    __CHK:BYTE
        EXTRN    ___wcpp_4_data_init_fs_root_:BYTE
        EXTRN    __argc:BYTE
        EXTRN    _cstart_:BYTE
DGROUP        GROUP    CONST,CONST2,_DATA,_BSS
_TEXT        SEGMENT    BYTE PUBLIC USE32 'CODE'
        ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP

; int foo()
`W?foo$n()i`:
    push        4
    call        near ptr FLAT:__CHK

; {
;   return 0; // Nötig, sonst Fehlermelung vom Compiler und Abbruch der Übersetzung
; }
    xor         eax,eax
    ret        

;
; int main (int argc, char * argv []) // OHNE extern "C"!
main_:
    push        4
    call        near ptr FLAT:__CHK

; {
;     foo();
    call        near ptr FLAT:`W?foo$n()i`

;     return 0;
; }
    xor         eax,eax
    ret        
_TEXT        ENDS
CONST        SEGMENT    BYTE PUBLIC USE32 'DATA'
CONST        ENDS
CONST2        SEGMENT    BYTE PUBLIC USE32 'DATA'
CONST2        ENDS
_DATA        SEGMENT    BYTE PUBLIC USE32 'DATA'
_DATA        ENDS
_BSS        SEGMENT    BYTE PUBLIC USE32 'BSS'
_BSS        ENDS

        END



Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.05.2012, 14:42 Uhr
0xdeadbeef
Gott
(Operator)


Naja, im Standard ist ja ausdrücklich festgelegt, dass main nicht überladen werden kann, also macht es für einen Compilerbauer Sinn, das fest zu verdrahten.

Sag mal, schlägst du dich immer noch mit diesem Watcom-Compiler herum? Dem fehlt doch immer noch die halbe Standardbibliothek.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
23.05.2012, 22:25 Uhr
Hans
Library Walker
(Operator)



Zitat von 0xdeadbeef:

Sag mal, schlägst du dich immer noch mit diesem Watcom-Compiler herum? Dem fehlt doch immer noch die halbe Standardbibliothek.

Nun ja, ich hab lange nichts mehr programmiert und ausserdem bis vor etwa 2 Wochen noch mit meinem uralten Rechner mit AMD-K6-Prozessor gearbeitet. Da lies sich die MinGW-Suite nicht Installieren ohne das ich Platzprobleme auf der Festplatte (6GB) bekommen hätte. Da war der Watcom wesentlich Resoucenfreundlicher. Und dass dem die halbe Standardbibliothek fehlt, fiel meisstens nur an zwei Stellen auf: zum einen, wenn ich versucht habe, Deine speziellen Codebeispiele zu übersetzen, zum anderen wenn ich die Programme aus einem Astronomiebuch übersetzen wollte. Auf letzteres konnte ich aber auch verzichten, weil auch lauffähige Programme auf der CD zum Buch drauf sind.

Der "neue" Rechner ist zwar auch gebraucht, aber erst ca. 5 Jahre alt. Darin werkelt ein AMD Athlon 64 X2 Dual Core Prozessor mit 2,7 GHz. Ist für heutige Verhältnisse zwar auch nichts Grossartiges mehr, aber ein Quantensprung für mich.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
23.05.2012, 23:30 Uhr
0xdeadbeef
Gott
(Operator)


Naja, wenn ich mir die Watcom-Seite so ansehe...da fehlt die halbe Algorithmusbibliothek, und der Rest ist auch bestenfalls halb fertig. Ich meine,

Zitat:

<string>

Mostly complete. Although there are no I/O operators, all other member functions and string operations are available.

(...)

<vector>

Partially complete. Enough functionality exists to be useful. Some member functions are known to not yet be exception safe.


um nur mal zwei rauszugreifen...und wenn man sich die Historie so ansieht, scheint sich da auch seit anderthalb Jahren gar nichts und einige Zeit davor nur sporadisch mal etwas getan zu haben. Das Projekt sieht mir ziemlich tot aus.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
24.05.2012, 01:09 Uhr
Hans
Library Walker
(Operator)



Zitat von 0xdeadbeef:
... Das Projekt sieht mir ziemlich tot aus.

Da könntest Du recht haben...
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: