2016-08-20 1 views
4

Also das in C99:Kann die Beschriftung bei Mid-Stream-Deklaration in C nicht enthalten?

label: 
    int ret = function(of, stuff); 

gibt einen Fehler bei der Kompilierung, während dies:

label: 
    ; 
    int ret = function(of, stuff); 

funktioniert gut.

Ist das ein Compiler Bug? Oder ist das ein Fehler in der Definition des C-Standards? Oder wenn dies Teil des C99-Standards ist, würde sich vielleicht jemand zur Verteidigung des C-Standards erheben, um zu behaupten, dass dies vollkommen sinnvoll ist?

+2

"Vielleicht würde sich jemand für die Verteidigung des C-Standards einsetzen, um zu behaupten, dass das vollkommen Sinn macht" - nun, Sie sind sicherlich an der richtigen Stelle angekommen. –

+0

Warum diese Stimmen stimmen ...: -S - eine faire Frage, an die ich mich noch gut erinnere ...:-) – alk

+0

Offenbar geht es bei Fragen zu einer Programmiersprache nicht um Programmierung? –

Antwort

7

Etiketten, die in N1256 definiert sind. 6.8.1 Beschriftete Anweisungen, können nur Anweisungen enthalten.

Syntax 
1  labeled-statement: 
      identifier : statement 
      case constant-expression : statement 
      default : statement 

int ret = function(of, stuff); ist eine Erklärung, die in N1256 6.7 Erklärungen definiert und ist keine Aussage.

Statements sind unten in N1256 6,8-Anweisungen und Blöcke definiert:

Syntax 
1  statement: 
      labeled-statement 
      compound-statement 
      expression-statement 
      selection-statement 
      iteration-statement 
      jump-statement 

compound-statement wird Blöcke, sogenannte die 0 oder mehr Erklärungen und durch {} umgeben Aussagen.

expression-statement ist Null oder ein Ausdruck definiert in N1256 6.5 Ausdrücke, gefolgt von einem Semikolon wie i++;. Der Ausdruck in der Syntax ist in N1256 6.5.17 Komma Operator definiert.

selection-statement ist if und switch Anweisung.

iteration-statement ist while, do-while und for Aussage.

jump-statement ist goto, continue, break und return Aussage.

Wie Sie sehen, sind Deklarationen keine Anweisung, Sie können also keine Beschriftungen zu Deklarationen hinzufügen.

+0

So könnte man zB haben. 'label: {int ret = funktion (von, stuff); } '. – detly

4

Möglicherweise ein Fehler in der Spezifikation - wenn es geändert wurde, um Anweisungen und Deklarationen in einem Block zu mischen (anstatt alle Deklarationen vor Anweisungen zu erfordern), sollte es auch geändert werden, um Beschriftungen auf einer Deklaration zuzulassen, Aber es war nicht so. Ein Artefakt, wie sich die Sprache im Laufe der Zeit entwickelt hat.

Es ist kein großes Problem, wie Sie entdeckt haben, wie Sie es trivial umgehen können, indem Sie das Label auf eine leere Anweisung vor der Deklaration setzen.

+0

Vielleicht beachten Sie jedoch, dass der gleiche Niggle und Workaround vor C99 für abschließende Fälle (oder Beschriftungen) in einem Schalter liegt. Ich vermute, dass das Erfordernis einer nachfolgenden Aussage eine Mehrdeutigkeit auflöst oder das Leben für den Parser auf andere Weise erleichtert. – doynax

+0

Es würde mich nicht wundern, wenn der Zweck des Verbots von Erklärungen, die Aussagen folgen, tatsächlich darin bestand, sicherzustellen, dass es unmöglich war, von einem Punkt nach einer Deklaration zu einem Punkt vor der Deklaration zu springen, ohne den Geltungsbereich dieser Deklaration zu verlassen. Die Tatsache, dass alle Variablen in einer * function * jedem ausführbaren Code vorausgehen (wie es einige C-Compiles taten), vereinfacht die Codegenerierung, aber ich glaube nicht, dass die C89-Regeln einen echten Vorteil bieten, außer dass der Code die Kontrolle an einen Punkt überträgt bevor eine Erklärung notwendigerweise ihren Geltungsbereich verlassen muss. – supercat

Verwandte Themen