Diego Orellana
Diego Orellana

Reputation: 1024

Is there any difference between the directive #include from C and the one from C++?

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)".

Upvotes: 3

Views: 263

Answers (3)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

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.

Upvotes: 9

o11c
o11c

Reputation: 16156

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).

Upvotes: 1

T.C.
T.C.

Reputation: 137404

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.

Upvotes: 9

Related Questions