5

I just read a question on SO discussing scenarios in which a piece of code is valid in both C and C++ but would produce different behavior in each language.

This begs the question: Could this ever be a problem when including C headers in C++ code?

I know from this question that you should include C headers like this:

extern "C" {
#include <your_os_or_library_header_in_c.h>
}

But all I found so far is that the extern "C" only guarantees that name mangling is turned off.

I couldn't find any information on whether it evaluates all statements as C, so that e.g. sizeof('a') or 10 //* comment */ 2 (which you could find in an inline function) are parsed as C and not C++. (Note that relying on such behavior as someone who writes a C header is obviously a bad idea, but I'm asking it from a purely academic standpoint of "What if?".)

Does the C++ standard say that enclosing a block of code in extern "C" means that all statements in it must be parsed as C?

Community
  • 1
  • 1

2 Answers2

7

extern "C" is a C++ construct which affects language linkage in a C++ program. It does not switch the language to C in any way. All source text inside an extern "C" declaration is still parsed as C++ and as C++ only.

Note that extern "C" affects more than just name mangling - it is (theoretically) possible that functions with C and C++ language linkage could have different calling conventions, for example.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thank you. I should maybe add the question: "Is this ever going to be a problem in the Real World™?" Or would any sane developer of an OS or library header strictly avoid such problems and make sure the *header itself* produces the same behavior in both C and C++? – Alec Bender Nov 12 '13 at 13:08
3

extern "C" only changes linking, i.e. mangling and possibly the calling convention. Try compiling and running this program with both a C and a C++ compiler:

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
    inline void putsizeofchar()
    {
        printf("%zd\n", sizeof(char));
    }
#ifdef __cplusplus
}
#endif

int main()
{
    putsizeofchar();
    return 0;
}

Since header inclusion is textual substitution in both languages, the lack of a header doesn't make any difference.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Thank you. I should maybe add the question: "Is this ever going to be a problem in the Real World™?" Or would any sane developer of an OS or library header strictly avoid such problems and make sure it produces the same behavior in both C and C++? – Alec Bender Nov 12 '13 at 13:03
  • 1
    @AlecBender: no developer in their right mind writes programs that are both C and C++ at the same time. Instead, they pick either language for the implementation, then use `extern "C"` to make sure it has an API for the other one. – Fred Foo Nov 12 '13 at 13:05
  • I think you misunderstood my comment. I wasn't talking about writing *programs* that are both C and C++ at the same time, but writing the *headers* for their interface in a way that produces the documented behavior in both C and C++ (ie no inline functions that do what you did in your example.) – Alec Bender Nov 12 '13 at 14:34
  • @AlecBender: I put inline functions in a lot of my C++ headers :) But if you want C/C++ interop via a header, then make sure the header is pure C except for the `extern "C"` and include it in the C++ modules that implement it to make sure they get compiled the right way. – Fred Foo Nov 12 '13 at 18:27