2014-02-07 13 views
5

Beim Kompilieren des folgenden Snippets geben sowohl gcc als auch clang nur eine Warnung aus. Hinweis Raum nach \ neben int:Warum geben sowohl clamg als auch gcc nur dann eine Warnung aus, wenn ein Leerzeichen nach dem Backslash vorhanden ist, wenn der C-Standard angibt, dass Leerzeichen verboten sind?

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int \ 
     a = 10; 

    printf("%d\n", a); 
} 

gcc:

main.c:7:6: warning: backslash and newline separated by space [enabled by default]

Klirren:

main.c:7:7: warning: backslash and newline separated by space int ^

In C99-Standard in 5.1.1.2 heißt es:

Each instance of a backslash character() immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines.

Warum entsprechen C-Compiler nicht dem C-Standard? Ich denke, es ist nur ihre Schöpfer Entscheidung nicht zu. Ich habe eine Nachricht in der GCC-Mailingliste gefunden, die dieses Verhalten eingeführt hat: http://gcc.gnu.org/ml/gcc-patches/2000-09/msg00430.html. Dort sagen sie, dass dies getan wird, weil nachfolgende Leerzeichen selten sind und sie sie nicht als Fehler behandeln wollen. Wie häufig ist das?

+4

Es gibt einen Unterschied zwischen der Nichteinhaltung des C-Standards und der Kompilierung von nicht-konformen Programmen. Hier machen GCC und Clang das letztere. –

Antwort

3

Der Compiler darf die Sprache erweitern, solange das Dokument die Änderung, die gcc in ihren Dokumenten in Abschnitt 6.21 Slightly Looser Rules for Escaped Newlines tut.

Recently, the preprocessor has relaxed its treatment of escaped newlines. Previously, the newline had to immediately follow a backslash. The current implementation allows whitespace in the form of spaces, horizontal and vertical tabs, and form feeds between the backslash and the subsequent newline. The preprocessor issues a warning, but treats it as a valid escaped newline and combines the two lines to form a single logical line. This works within comments and tokens, as well as between tokens. Comments are not treated as whitespace for the purposes of this relaxation, since they have not yet been replaced with spaces.

und clangstrives to supportgcc Erweiterungen und verweist auf die gcc docs auf sie:

this document describes the language extensions provided by Clang. In addition to the language extensions listed here, Clang aims to support a broad range of GCC extensions. Please see the GCC manual for more information on these extensions.

So ihre Verpflichtungen in Bezug auf die Norm erfüllt sind. In der Tat Linux depends on many gcc extensions.Wir können sehen, um den Entwurf des C99 Standardkollektion 4.Conformance Absätzen , die sagen:

[...]A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.3)

Fußnote 3 sagt:

This implies that a conforming implementation reserves no identifiers other than those explicitly reserved in this International Standard.

und Absatz :

An implementation shall be accompanied by a document that defines all implementation defined and locale-specific characteristics and all extensions.

auchDokumente, die Sie die -pedantic Flagge zu generate a warning when using extensions verwenden können und Sie -pedantic-errors Flag verwenden können, um sie einen Fehler zu machen:

[...] to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).

3

Compile mit den richtigen Optionen und gcc und clang wird sich weigern, die Übersetzung zu tun:

$ gcc -Wall -Werror -std=c11 -pedantic tst.c 
tst.c: In function ‘main’: 
tst.c:6:9: error: backslash and newline separated by space [-Werror] 
cc1: all warnings being treated as errors 
$ 

standardmäßig gcc kompiliert in c89-Modus mit GNU-Erweiterungen aktiviert und ist ziemlich nachsichtig.

+0

c89-Modus ist nicht relevant; gcc akzeptiert dies und warnt mit '-std = c89' oder' -std = c99' oder, ich erwarte, '-std = c11', auch ohne' -Wall'. Es ist '-Werror', der es zu einem Fehler ändert. –

2

A warning is generated when this happens. Don't write code that depends on this behavior; it is provided because trailing whitespace is significant (almost) nowhere else, and we get much better error recovery if we treat them as line continuations. Especially don't write code that depends on being able to put a comment after a line continuation, that is an accident of the implementation and will change in the future.

Wenn Sie Erweiterungen deaktivieren, wie die andere Antwort sagt, Warnungen aktivieren und -pedantic-errors verwenden. Ansonsten können Sie alle Funktionen des Compilers nutzen, solange Sie die Implikationen verstehen und welche Vorteile sie bieten. Wenn Sie den C99-Modus wünschen, stellen Sie sicher, dass Sie -std=c99 zur Befehlszeile hinzufügen.

1

Sie zitierte Text aus dem Standard, der sagt, was passiert, wenn ein Backslash durch eine neue Zeile folgt.

Dieser Text sagt uns nicht, was der Compiler (oder C-Implementierung im Allgemeinen) tun muss, wenn es einen Backslash gefolgt von einem Leerzeichen gibt.

Ich sehe keine bestimmte Regel dafür in der C-2011-Standard. Ein umgekehrter Schrägstrich außerhalb seines richtigen Platzes entspricht einfach nicht der allgemeinen Syntax und Grammatik von C, so dass es zu einer Art von Verletzung dieser Zeichen kommt, je nachdem, wo es erscheint.

C 2011 5.1.1.3 sagt:

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint,…

GCC das tat; es erzeugt eine Diagnosemeldung. (Eine Warnung ist eine Diagnose.) So entsprach sie in dieser Hinsicht dem C 2011.