2016-03-29 9 views
3

Nein diese Frage wird nicht in der Post beantwortet Was ist der Unterschied zwischen #include <filename> und #include “filename”? Das ist eine andere Frage. Ich untersuche die Unterschiede zwischen C und C++. Ich tue dies, indem sie die grundlegenden Programme zu vergleichen, die Sie jede Sprache machen können:Gibt es einen Unterschied zwischen der Direktive #include von C und der von C++?

In C:

#include <stdio.h> 
int main() 
{ 
    printf("Hello World"); 
    return 0; 
} 

In C++

#include <iostream> 
int main() 
{ 
    std::cout << "Hello World!!!" << std::endl; 
    return 0; 
} 

Ich weiß, über Header und den Übersetzungsvorgang. Aber ich würde gerne wissen, ob es einen Unterschied zwischen der # include-Direktive von C und C++ gibt. Wie zum Beispiel der Header-Inhalt, wenn kopiert wird, wird auf andere Weise kopiert. Ich denke, diese Frage ist sehr einfach, Sie können es mit "Nein" oder "ja, hier sind die Unterschiede: 1), 2)" beantworten.

+1

Ich denke, diese Frage muss viele Duplikate haben. –

+0

Ich denke Header Inhalt wird nicht von beiden Sprachen "kopiert". – usr2564301

+1

'# include' ist eine CPP-Anweisung (** C **/C++ ** P ** re ** P ** rocessor) und kein C- oder C++ - Befehl. – callyalater

Antwort

9

Ja, es gibt mindestens zwei Unterschiede. In C++ (WG21 N4567 [cpp.include]/5):

Die Umsetzung wird eindeutige Zuordnungen für Sequenzen liefern bestehend aus einem oder mehreren nondigit s oder digit s (2,10), gefolgt von einer Zeitraum (.) und eine einzige nicht-. Das erste Zeichen darf nicht a Ziffer sein. Die Implementierung kann Unterschiede zwischen dem alphabetischen -Fall ignorieren.

in C (WG14 N1570 6.10.2/5, Hervorhebung von mir):

Die Umsetzung wird eindeutige Zuordnungen für Sequenzen liefern bestehend aus einem oder mehreren nondigits oder Ziffern (6.4.2.1), gefolgt durch eine Periode (.) und eine einzige Nichtigit. Das erste Zeichen darf keine Ziffer sein. Die Implementierung kann Unterschiede des alphabetischen Falls und ignorieren, um die Zuordnung auf acht signifikante Zeichen vor der Periode einzuschränken.

Eine konforme C-Implementierung kann "foobarbaz.h" und "foobarbat.h" derselben Quelldatei zuordnen. Eine konforme C++ - Implementierung kann nicht.


Zusätzlich wird in C (N1570 6.4.7):

Wenn die Zeichen ', \, ", // oder /* in der Sequenz Trennzeichen zwischen den < und > auftreten, das Verhalten ist nicht definiert. Und falls die Zeichen ', \, // oder /* in der Sequenz zwischen den Begrenzern " auftreten, das Verhalten undefiniert.

während in C++ (N4567 [lex.header]/2):

Das Auftreten von einem des Zeichens ' oder \ oder entweder von die Zeichenfolge /* oder // in einem q-char-Sequenz oder h-char-Sequenz ist bedingt unterstützt mit implementierungsdefinierten Semantik, wie das Aussehen deristZeichen " in einer h-char-Sequenz.

„bedingt gestütztes mit Implementierung definiert die Semantik“ bedeutet, dass

  • es, wenn die Durchführung nicht unterstützt, sie eine Diagnose ausgeben muss;
  • Wenn die Implementierung dies unterstützt, muss ihre Interpretation dieses Konstrukts dokumentiert werden.

während "undefined Verhalten" bedeutet, dass die Implementierung tun kann, was sie will.

+0

Vielen Dank für Ihre Antwort T.C. –

+0

TL; DR: In der Praxis gibt es keine Unterschiede, es sei denn, Sie haben wirklich kaputten Quellcode. –

9

Wie zum Beispiel vielleicht der Header Inhalt kopiert wird, wenn kopiert wird auf andere Weise kopiert.

Die #include Präprozessordirektive vom CPP-Vorprozessor gehandhabt wird, ist, dass (meist) die gleiche für C und C++ Kompilierung. Abweichende C- und C++ - Standards könnten subtle differences einführen, aber keiner davon wirkt sich darauf aus, wie die #include-Direktive bezüglich der Ersetzung des Dateiinhalts in die Übersetzungseinheit gehandhabt wird (neben der Erweiterung und Übereinstimmung der Header-Dateinamen siehe answer) .

Das CPP ersetzt lediglich den Text und erweitert lediglich die Inhalte der enthaltenen Datei in die Übersetzungseinheit, sei es C- oder C++ - Code.

Ich denke, diese Frage ist sehr einfach, Sie können es mit "Nein" oder "ja, hier sind die Unterschiede: 1), 2)" beantworten.

Nein, es gibt keine Unterschiede für die #include Direktive arbeitet in Bezug auf den Text Ersatz.


Nun, aus den Ergebnissen der C-Compiler möglicherweise nicht in der Lage sein, Code zu kompilieren von C++ Header-Dateien erweiterte richtig, und manchmal umgekehrt.

+0

Es wurde neulich erwähnt, dass C++ - Präprozessor unterscheidet sich von C Präprozessor, aber ich habe keinen bestimmten Unterschied gesehen. – SergeyA

+0

@SergeyA _ "Es wurde neulich erwähnt ..." _ Haben Sie einen speziellen Link für diese Erwähnung? Ich bin nur neugierig, was der Unterschied eigentlich sein sollte. –

+0

Ich dachte, es gäbe einen Unterschied in der Toleranz, wenn ein # # if' '# endif 'sich auf 2 verschiedene Dateien oder eine andere ähnlich fragwürdige Programmierpraxis - IDK - verteilt. Aus praktischen Gründen kenne ich keinen Unterschied. – chux

1

In C++ werden normalerweise mehr Verzeichnisse durchsucht. Dies ist technisch kein Unterschied in der Direktive, obwohl.

Zum Beispiel auf meinem System:

% gcc -E -v -x c - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p' 
/usr/lib/gcc/x86_64-linux-gnu/5/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64 
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" 
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include" 
#include "..." search starts here: 
#include <...> search starts here: 
/usr/lib/gcc/x86_64-linux-gnu/5/include 
/usr/local/include 
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed 
/usr/include/x86_64-linux-gnu 
/usr/include 
End of search list. 
% gcc -E -v -x c++ - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p' 
/usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE - -mtune=generic -march=x86-64 
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/5" 
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" 
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include" 
#include "..." search starts here: 
#include <...> search starts here: 
/usr/include/c++/5 
/usr/include/x86_64-linux-gnu/c++/5 
/usr/include/c++/5/backward 
/usr/lib/gcc/x86_64-linux-gnu/5/include 
/usr/local/include 
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed 
/usr/include/x86_64-linux-gnu 
/usr/include 
End of search list. 

Darüber hinaus gibt es Unterschiede zwischen den Präprozessoren, die tun nicht beinhalten #include:

  • benannte Betreiber gebautet in C++. In C müssen Sie #include <iso646.h>
  • boolesch Schlüsselwörter sind in C++ eingebaut. In C müssen Sie #include <stdbool.h>
  • Seit C++ 14, ' ist als Zifferntrennzeichen verfügbar. (Es ist allgemein anerkannt, dass dies eine schlechte Idee war, aber das Komitee würde nichts anderes akzeptieren).