2013-09-23 12 views
10

ich folgenden Code habe, die ich mit gcc#define und #include Ordnung in C

#include<stdio.h> 
#include<stdbool.h> 
#define true 9 
int main() { 
    printf("TRUE = %d\n",true); 
    return 0; 
} 

kompilieren Und ich bekomme Fehler

test.c:3:0: warning: "true" redefined [enabled by default] 
In file included from test.c:2:0: 
/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdbool.h:34:0: note: this is the location of the previous definition 

Aber wenn ich ändern den Code ein bisschen

#include<stdio.h> 
#define true 9 
#include<stdbool.h> 
int main() { 
    printf("TRUE = %d\n",true); 
    return 0; 
} 

Ausgabe:

TRUE = 1 

Frage:

ich den Grund für Fehler in ersten Fall verstehen, aber im zweiten Fall, wenn ich true definieren, bevor ich #include<stdbool.h>, warum es true neu zu definieren, erlaubt?

Update:

Hier ist stdbool.h.

ersten Zeilen sind

#ifndef _STDBOOL_H 
#define _STDBOOL_H 

#ifndef __cplusplus 

#define bool _Bool 
#define true 1 
#define false 0 

, die nichts, wie in der Yu Hao ‚s answer ist.

+4

Ich hoffe, Sie denken nicht ernsthaft über die Definition von True – Bathsheba

+2

@Bathsheba Ich denke, das OP macht einen Test, also braucht er einen anderen Wert als '1' zu sehen, welches Makro funktioniert. –

Antwort

7

Obwohl Yu Hao die Frage possible answer gab, sind die Dinge in der Tat hier anders.

Dies konnte leicht durch den Blick in stdbool.h zu erkennen, dass es keine #ifdef ... #endif "Guard" um die Definition von true.

Außerdem unterdrückt GCC einfach Warnungen, die für Probleme in Systemheadern gegeben werden sollten * 1.

Verwenden Sie die gcc-Option -isystem, damit das erste Beispiel sich wie das zweite verhält.

From the gcc manual:

Die Header-Dateien Schnittstellen zum Betriebssystem und Laufzeitbibliotheken oft in streng geschrieben sind nicht zu erklären, daher C. konform, gibt GCC Code in System spezielle Behandlung headers gefunden. Alle Warnungen, die nicht durch "#warning" (siehe Diagnose) generiert werden, werden unterdrückt, während GCC einen Systemheader verarbeitet. Makros, die in einem Systemheader definiert sind, sind immun gegen einige Warnungen, wo immer sie erweitert werden. Diese Immunität wird auf Ad-hoc-Basis gewährt, wenn wir feststellen, dass eine Warnung aufgrund von Code in Makros, die in Systemheadern definiert sind, viele falsche positive Ergebnisse generiert.

[...]

Die -isystem Befehlszeilenoption ergänzt die Liste der Verzeichnisse sein Argument für Header zu suchen, wie -I. Alle Header, die in diesem Verzeichnis gefunden werden, werden als System-Header betrachtet.


* 1: System-Header enthalten sind Header in <> Klammern.

+0

Hmm '-isystem' scheint keine Warnung für mich in' gcc' zu erzeugen, aber +1 ist eine bessere Erklärung. –

+0

@ShafikYaghmour: Sry, ich habe es gemischt. Bitte beachten Sie meine korrigierte Antwort. – alk

+0

@alk Kein Fehler aufgrund einer unterdrückten Warnung, weil "GCC den Code in den Systemköpfen als Sonderbehandlung angibt."? – TheKojuEffect

9

In der Datei stdbool.h kann der Code wie folgt aussehen:

#ifdef true 
#undef true 
#define true 1 
#endif 

Sie sollten das gleiche tun, wenn das Makro vor definiert werden kann. Ein weiterer ähnlicher Trick ist, wie folgt aus:

#ifndef MAGIC 
#define MAGIC 42 
#endif 

EDIT

stellte sich heraus, dieses ist gcc's feature finden @alk's answer zum Detail.

Alle Warnungen, die nicht durch '#warning' generiert wurden, werden unterdrückt, während GCC einen Systemkopf verarbeitet. Makros, die in einem Systemheader definiert sind, sind immun gegen einige Warnungen, egal wo sie erweitert werden.

+2

Nun, es müsste "# ifdef" und dann "# undef" sein, da im zweiten Beispiel der Wert von "stdbool.h" gedruckt wird und nicht das manuelle "# define". – svk

+0

@YuHao Überprüfen Sie meine aktualisierte Frage. – TheKojuEffect

+2

"* ... der Code könnte aussehen ... *": aber nicht. Bitte sehen Sie meine Antwort auf diese Frage. – alk

-1

Nun, Ihre Warnung schon sagt es:

test.c:3:0: warning: "true" redefined [enabled by default] 

GCC können Sie Werte neu definieren, wenn Sie es ausdrücklich sagen, nicht zu tun. Sie können -Werror dafür verwenden.