2014-09-17 9 views
12

Der C-Standard besagt, dass Variablennamen nicht mit Standard-C-Schlüsselwörtern und Standardfunktionsnamen übereinstimmen sollten. Warum kompiliert der folgende Code ohne Fehler?Sind gültige und fopen gültige Variablennamen?

#include <stdio.h> 

int main() 
{ 
    int main = 10; 
    printf("Magic is %d", main); 
    return 0; 
} 

Siehe auch http://codepad.org/OXk4lZZE

In einem answer unten ouah schreibt

main ist kein reservierter Bezeichner und es wird auf Namen Variablen als main in C erlaubt

unter Berücksichtigung des unten stehenden Programms, tha t bedeuten, dass fopen ist ebenfalls nicht reserviert?

#include <stdio.h> 

int main() 
{ 
    int fopen = 10; 
    printf("Magic is %d", fopen); 
    return 0; 
} 
+9

Der C-Standard sagt lotsa Dinge ... –

+1

löst, Interessanterweise ist die gesamte „main als globale Variable“ -Konzept in der Internationalen 1984 von einem Sjoerd Mullender eingesetzt wurde Verschleierter C-Code-Wettbewerb. Siehe [hier] (http://ioccc.org/1984/mullender.c). – SevenBits

Antwort

32

Ihr Programm ist ein gültiges C-Programm.

main ist kein reservierter Bezeichner und es zu Namensvariablen als main in C.

erlaubt ist

Was Sie nicht tun können, ist eine Variable main im Dateigültigkeitsbereich zu nennen, aber das ist das gleiche wie bei anderen Variablen, die im Widerspruch zu mit einer Funktion mit dem gleichen Namen:

Dies ist nicht gültig:

int main = 0; 

int main(void) 
{ 
} 

aus den gleichen Gründen nicht gültig:

int foo = 0; 

int foo(void) 
{ 
    return 0; 
} 

EDIT: die OP Frage bearbeiten zu adressieren, ist das zweite Programm in OP Frage gilt auch als C sagen

(C11, 7.1.3p1) „Alle Bezeichner mit externer Bindung in jedem der folgenden Unterklauseln (einschließlich der zukünftigen Bibliotheksanweisungen) und errno sind immer für die Verwendung als Bezeichner mit der externen Verknüpfung reserviert. "

aber der Variablenbezeichner hat einen Blockbereich und keine Verknüpfung im Beispielprogramm.

+1

Beachten Sie auch, dass '' fopen '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'sein kann. Dann wäre es nicht portierbar ("streng konform") wie bestimmte Arten von Variablen, speziell ein Funktionszeiger, den Sie wie 'fopen (was auch immer) 'nennen, da dies das Makro erweitern würde.Es wird als Variablenname funktionieren, vorausgesetzt, die Implementierung hat es nicht als Makro definiert, oder wenn Sie niemals den Variablennamen direkt vor einem '(' schreiben, so ist es ein ziemlich guter Punkt der Portabilität ... –

+0

Dies unterscheidet sich von die Tatsache, dass Sie bereits angeben, dass Standard-Bibliotheksfunktionsnamen für die Verwendung mit externer Verknüpfung reserviert sind, da diese Verknüpfungsregel auch dann gilt, wenn Sie niemals den relevanten Header enthalten und nicht zuverlässig anders als mit den reservierten Identifikatoren abgearbeitet werden können und die "zukünftigen Richtungen". –

+0

@SteveJessop Es ist ein interessanter Punkt, danke für den Kommentar. Im Beispiel von OP mit 'fopen' erklärt als ein' int' die Tatsache, dass 'fopen' als ein funktionsähnliches Makro in der Header hat keinen Einfall, aber ein anderes Beispiel mit einem Funktionszeiger und einem Aufruf des Mauszeigers wäre in der Tat problematisch. – ouah

1

Standardmäßig sind die globalen Variablen und die Funktionen extern in der Natur, wo sie im Blockbereich standardmäßig auto sind.

Um zu überprüfen, wie der Linker die Symbole überprüfen here