3

No this question is not answered in the post What is the difference between #include <filename> and #include “filename”? This is a different question. I am studying the differences between C and C++. I am doing this by comparing the most basic programs that you can make of each language:

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; } 

I know about headers and the compilation process. But i would like to know if there is any difference between the #include directive of C and C++. Like for example maybe the header content when is copied is copied in a different way. I think this question is very straightforward, you can answer it by saying "No" or "yes, here are the differences: 1), 2)".

10
  • 1
    I think this question has got to have plenty of duplicates. Commented Mar 29, 2016 at 17:24
  • 1
    #include is a CPP (C /C++ P re P rocessor) directive, and not a C or C++ command. Commented Mar 29, 2016 at 17:30
  • 1
    One could argue that the C program presented is an even more basic C++ program than is the presented C++ analog. Commented Mar 29, 2016 at 17:33
  • 6
    I don't understand the many downvotes, that's a legit question for a beginners doubts if #include works the same way for c and c++. So find a dupe or shut up. Commented Mar 29, 2016 at 17:36
  • 2
    Possible duplicate of What is the difference between #include <filename> and #include "filename"? Commented Mar 29, 2016 at 17:39

3 Answers 3

9

Yes, there are at least two differences. In C++ (WG21 N4567 [cpp.include]/5):

The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits (2.10) followed by a period (.) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case.

In C (WG14 N1570 6.10.2/5, emphasis mine):

The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits (6.4.2.1) followed by a period (.) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case and restrict the mapping to eight significant characters before the period.

A conforming C implementation can map "foobarbaz.h" and "foobarbat.h" to the same source file. A conforming C++ implementation cannot.


Additionally, in C (N1570 6.4.7):

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

while in C++ (N4567 [lex.header]/2):

The appearance of either of the characters ' or \ or of either of the character sequences /* or // in a q-char-sequence or an h-char-sequence is conditionally-supported with implementation-defined semantics, as is the appearance of the character " in an h-char-sequence.

"conditionally-supported with implementation-defined semantics" means that

  • if the implementation doesn't support it, it must issue a diagnostic;
  • if the implementation does support it, its interpretation of this construct must be documented.

while "undefined behavior" means that the implementation can do whatever it wants.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer T.C.
TL;DR: In practice, there are no differences unless you have some really broken source code.
9

Like for example maybe the header content when is copied is copied in a different way.

The #include preprocessor directive is handled by the CPP preprocessor, that is (mostly) the same for C and C++ compilation. Diverging C and C++ standards might introduce subtle differences, but none of these affects how the #include directive should be handled regarding how the file's content is replaced into the translation unit (besides how the header file names are expanded and matched, see @T.C.'s answer).

The CPP does merely text replacement and just expands what's seen from the included file into the translation unit, be it C or C++ code.

I think this question is very straightforward, you can answer it by saying "No" or "yes, here are the differences: 1), 2)".

No, there's no differences for the #include directive is working regarding the text replacement.


Well, from the results the C compiler might not be able to compile code expanded from C++ header files correctly, and sometimes vice versa.

10 Comments

It's been mentioned the other day that C++ preprocessor is different from C preprocessor, but I did not see any specific difference.
@SergeyA "It's been mentioned the other day ..." Do you have a specific link for this mentioning? I'm just curious what the difference should actually be.
I thought there was a difference in the tolerance of having a #if #endif spread across 2 different files or some other similar questionable programming practice - IDK. Yet for practical concerns, I know of no difference,.
@πάνταῥεῖ, I found the links for the differences: stackoverflow.com/questions/5085533/… and stackoverflow.com/questions/21515608/…
@SergeyA THX a lot. Though at least there aren't any differences how the #include directive is handled, right?
|
1

In C++, there are typically more directories being searched. This is technically not a difference in the directive, though.

For example, on my 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. 

Additionally, there are differences between the preprocessors that do not involve #include:

  • named operators are builtin in C++. In C, you must #include <iso646.h>
  • boolean keywords are builtin in C++. In C, you must #include <stdbool.h>
  • Since C++14, ' is available as a digit separators. (It is universally agreed that this was a bad idea, but the committee wouldn't accept anything else).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.