2016-07-05 9 views
3

Soweit ich weiß, in C oder C++, sollte die Signatur von main entweder int main(void) (void ist optional in C++) oder int main(int, char**) sein. Jedoch der folgende Code kompiliert ohne Warnungen (-Wall -Wextra -Wpedantic) in gcc/g ++/Klappern/Klirren ++Können wir den Argumenten von main CV-Qualifier hinzufügen?

int main(int, const char * const * const argv){} 

Live on Coliru

Ist der Code oben legal? Mit anderen Worten, können wir den Argumenten von main CV-Qualifier hinzufügen, oder ist das nur eine Erweiterung des Compilers, die keine Diagnose benötigt?

+0

Sie können es hinzufügen. – STF

+0

@STF Ich sehe das, aber haben Sie eine Standardreferenz? Soweit ich mich erinnere (und ich habe jetzt nicht den Standard vor mir), wird die Signatur zu "int main()" oder "int main (int, char **)", oder syntaktischem Zucker, 'int main (int, char * [])'. – vsoftco

+1

@Galik Warum? Die Zeiger sind nicht implizit konvertierbar, es ist kein standardmäßiger Verfall von Array zu Pointer. Also sollten die CV-Quals Teil der Signatur sein. Vielleicht vermisse ich hier etwas. – vsoftco

Antwort

4

Der C++11 Standard erlaubt der Implementierung, jede Unterschrift zu akzeptieren, die es mag, es erfordert nur die zwei, die in Frage gestellt werden. Es muss auch einen Rückgabetyp von int haben.

3.6.1 Hauptfunktion [basic.start.main]

Eine Implementierung ist nicht die Hauptfunktion vordefinieren. Diese Funktion darf nicht überlastet werden. Es muss einen Rückgabetyp vom Typ int haben, ansonsten ist der Typ implementationsdefiniert.

int main() { /* ... 
*/ } 

und

int main(int argc, char* argv[]) { /* ... 
*/ } 

So die Hauptfrage zu adressieren: Alle Implementierungen müssen beiden folgenden Definitionen von Haupt erlauben

Können wir hinzufügen CV-Qualifikations zu den Argumenten von main?

Wir können wenn die Umsetzung unterstützt es aber wenn wir das tun, dann der Code ist weniger wahrscheinlich tragbar zu sein.

Der Code nur dann voll tragbar sein wird, wenn es (höchstens) cv Qualifier dem Parameter Variable fügt sich, nicht seine spitzen-to-Typen:

// still portable, same signature as int main(int, char**) 
int main(int, char** const argv); 

// not portable 
int main(int, char* const* argv); 

// not portable 
int main(int, const char** argv); 
+0

Vielen Dank, kristallklar! – vsoftco

+0

Dies ist wörtlich richtig, weil die Signatur einer Funktion nicht den Rückgabetyp enthält (der für "main" "int" sein muss). –

+0

@ Cheersandhth.-Alf Das sagst du aber * ansonsten ist sein Typ implementierungsdefiniert * bezieht sich auf den Rückgabetyp? – vsoftco

3

Denken Sie daran, dass C und C++ zwei verschieden sind Sprachen. Die Antwort ist für beide ziemlich gleich, aber es lohnt sich, zu bedecken, was die C standard auch sagt - vor allem angesichts der Sprache-Anwalt-Tag. Die Verbindung ist zu dem N1570 Entwurf von C11.

Abschnitt 5.1.2.2.1 umfasst die Definition von main für gehostete Implementierungen:

Die Funktion beim Programmstart aufgerufen genannt wird main. Die Implementierung deklariert keinen Prototyp für diese Funktion.Es ist zu mit dem Rückgabetyp int und ohne Parameter definiert:

int main(void) { /* ... */ }

oder mit zwei Parametern (hier bezeichnet als argc und argv, obwohl irgendwelche Namen kann verwendet werden, da sie lokal für die Funktion in sind, für die sie deklariert sind):

int main(int argc, char *argv[]) { /* ... */ }

oder gleichwertig; oder in einer anderen implementierungsdefinierten Weise.

Eine Definition mit zugesetztem const oder volatile Qualifier ist nicht gleichwertig auf die gezeigten Formen, also eine Implementierung, sie anzunehmen nicht verpflichtet ist. Da dieser Abschnitt jedoch kein Constraint ist, ist auch keine Implementierung erforderlich, um sich darüber zu beschweren. Und insbesondere, wenn eine Implementierung dokumentiert, dass sie const und/oder volatile Qualifizierer akzeptiert, dann sind sie perfekt für diese Implementierung.

(In der Praxis die meisten Compiler wird wahrscheinlich nicht beschweren.)

Beachten Sie, dass diese nur gehostet Implementierungen gilt. Für eine freistehende Implementierung (in der Regel für ein eingebettetes Ziel ohne OS):

... der Name und die Art der Funktion bei Programm Startup namens sind die Implementierung definiert.

(5.1.2.1 Absatz 1), was bedeutet, dass es keine tragbaren Definitionen der Hauptfunktion für freistehende Implementierungen (nicht einmal main genannt werden muss).

+0

Danke für die Standard-Angebote! – vsoftco