1

c++ compiler could compile code like this, and it executed correctly

#include <stdio.h>
int main() {
    printf("test...\n");
    return 0;
}

I think printf.c will be compiled to printf.o with c compiler, I just checked the stdio.h, there is no extern "C" keyword, then how could c++ linker link printf in printf.o which is compiled with c compiler?(By the way, my platform is ubuntu 14.04, compiler is gcc 4.8.4)

cong
  • 1,105
  • 1
  • 12
  • 29
  • Just because the `C` standard library contains a `printf()` doesn't mean the `C++` standard library can't provide one too. Mostly it is included to allow easy migration of source code written in `C` being ported to `C++`. – Galik Oct 23 '16 at 03:30
  • @Galik: Which is a good way to mess all up, as C is a different language with relevant differences even for identical syntax. But there still has to be specified the C calling conventions to the C++ compiler. – too honest for this site Oct 23 '16 at 03:32
  • 1
    @Olaf The `C++` standard recommends `C++` language linkage for the `C library` functions but leaves the actual decision to the implementation - so they *can* use `extern "C" {}` if they choose. – Galik Oct 23 '16 at 03:42

4 Answers4

3

printf is part of the C++ standard library.

The <stdio.h> header that you include in the C++ source, belongs to the C++ standard library, and is not necessarily the same contents as a C compiler will include.

How the C++ implementation leverages the corresponding C implementation (if at all) is an implementation detail.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

When C++ was originally made it was effectively a superset of C. That is to say, you can code perfectly good C in the C++ environment, just by ignoring all of the features that C++ adds. That, and because nowadays most C compilers are C++ compilers in which you can code C, is why you can use printf.

Secondly, no object code is generated for stdio because it is already a library, and so you are linking your own .o code against the already compiled stdio library code, which will be located somewhere in your compilers directory.

Nonanon
  • 560
  • 3
  • 10
  • Nowadays, it's impossible to write good C code in C++. The second part of your answer isn't answer the question w.r.t. extern C – Danh Oct 23 '16 at 03:12
1

Nobody can give you a definitive answer without knowing what implementation you're using.

Cheers and hth. - Alf gave one possibility, which is that the stdio.h that is included by a C++ program may not be the same as the stdio.h that is included by a C program. Another possibility is that it is the same header, and there is an extern "C" block, and you just can't see it. For example, I use gcc, and my /usr/include/stdio.h contains a __BEGIN_DECLS macro, which expands to extern "C" { when compiled as C++. See Do I need an extern "C" block to include standard C headers?

Community
  • 1
  • 1
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
-1

You may not see an explicit extern "C" in stdio.h, but it is there. It's just hiding.

For example, on Linux, in stdio.h we see this:

#include <features.h>

__BEGIN_DECLS

In <features.h> you will find the following:

# ifndef _SYS_CDEFS_H
#  include <sys/cdefs.h>
# endif

And in <sys/cdefs.h> you finally see:

#ifdef  __cplusplus
# define __BEGIN_DECLS  extern "C" {
# define __END_DECLS    }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

So, via a fairly roundabout path, Linux header files have a __BEGIN_DECLS/__END_DECLS wrapper which, when compiled by a C++ compiler, end up wrapping the whole thing inside extern "C".

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 1
    **−1** Re "but it is there", no, not necessarily. That is dis-information. – Cheers and hth. - Alf Oct 23 '16 at 03:47
  • @Cheersandhth.-Alf, you mean __BEGIN_DECLS in stdio.h is not necessary? – cong Oct 23 '16 at 11:28
  • @cong: In some cases the C++ library provides overloads of C library functions. For a given function name at most one of those overloads can have C linkage, or the linker couldn't distinguish them. Then why should any of them have C linkage? The C++ standard does not require C linkage of these functions. That's just disinformation. – Cheers and hth. - Alf Oct 23 '16 at 12:35