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

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Diego Orellana
  • 994
  • 1
  • 9
  • 20
  • 1
    I think this question has got to have plenty of duplicates. – barak manos Mar 29 '16 at 17:24
  • I think header content isn't "copied" by either language. – Jongware Mar 29 '16 at 17:26
  • 1
    `#include` is a CPP (**C** /C++ **P** re **P** rocessor) directive, and not a C or C++ command. – callyalater Mar 29 '16 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. – John Bollinger Mar 29 '16 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. – πάντα ῥεῖ Mar 29 '16 at 17:36
  • 2
    Possible duplicate of [What is the difference between #include and #include "filename"?](http://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename) – Evan Carslake Mar 29 '16 at 17:39
  • 1
    @EvanCarslake No, not really. I've been looking up that just before, but it doesn't answer if there are really differences for c or c++. – πάντα ῥεῖ Mar 29 '16 at 17:41
  • @callyalater In C, `#include` is called a _preprocessing directive_ and also call a _directive_. The "CPP (C /C++ P re P rocessor)" you mention is not in the C spec, but the functionality of `#include` is. C does not define " C command". – chux - Reinstate Monica Mar 29 '16 at 17:45
  • Thank you guys! Don't think I just post the question without doing some research... i didn't find the answer in any other post. Thank you alot πάντα ῥεῖ – Diego Orellana Mar 29 '16 at 17:49
  • "I am studying the differences between C and C++." While a noble undertaking, I question the purpose of it. It's not a good way to learn either - C++ is really a completely different language. It's best studied in isolation from C. – Kuba hasn't forgotten Monica Mar 31 '16 at 17:22

3 Answers3

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.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • It's been mentioned the other day that C++ preprocessor is different from C preprocessor, but I did not see any specific difference. – SergeyA Mar 29 '16 at 17:55
  • @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. – πάντα ῥεῖ Mar 29 '16 at 18:02
  • 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,. – chux - Reinstate Monica Mar 29 '16 at 18:02
  • @πάνταῥεῖ, I found the links for the differences: http://stackoverflow.com/questions/5085533/is-a-c-preprocessor-identical-to-a-c-preprocessor and http://stackoverflow.com/questions/21515608/what-are-the-differences-between-the-c-and-c-preprocessors – SergeyA Mar 29 '16 at 18:08
  • @SergeyA THX a lot. Though at least there aren't any differences how the `#include` directive is handled, right? – πάντα ῥεῖ Mar 29 '16 at 18:13
  • Certainly doesn't seem so. But, *the CPP preprocessor, that is the same for C and C++ compilation* is a general statement :) – SergeyA Mar 29 '16 at 18:16
  • @SergeyA I've integrated that into my answer. – πάντα ῥεῖ Mar 29 '16 at 18:20
  • "none of these affects how the `#include` directive should be handled" At least one does. – T.C. Mar 29 '16 at 18:32
  • @T.C. You mean the _"that the C++ preprocessor handles digraphs and universal character names, which are not present in C"_ part? – πάντα ῥεῖ Mar 29 '16 at 18:36
  • @πάνταῥεῖ, right, but now TC provided an ultimate anser. Sorry, my upvote goes to the Ultimate Answer On Difference and all. – SergeyA Mar 29 '16 at 18:40
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.

T.C.
  • 133,968
  • 17
  • 288
  • 421
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).
o11c
  • 15,265
  • 4
  • 50
  • 75