Do I need an extern "C" {}
block to include standard C headers in a C++ program. Only consider standard C headers which do not have counterparts in C++.
For example:
extern "C" {
#include <fcntl.h>
#include <unistd.h>
}
the extern keyword is used to extend the visibility of variables/functions. Since functions are visible throughout the program by default, the use of extern is not needed in function declarations or definitions. Its use is implicit.
All variables and functions in header files should be extern. Separate header files should be used for variables and functions. Use a C code file to declare the variables and functions and use this in end user code. Extern must be used instead of using global variables.
In C program should necessarily contain the header file which stands for standard input and output used to take input with the help of scanf() and printf() function respectively.
If you are including a C header file that isn't provided by the system, you may need to wrap the #include line in an extern "C" { /*... */ } construct. This tells the C++ compiler that the functions declared in the header file are C functions.
The system C headers usually already include a extern "C"
block, guarded by #ifdef __cplusplus
. This way the functions automatically get declared as extern "C"
when compiled as C++ and you don't need to do that manually.
For example on my system unistd.h
and fcntl.h
start with __BEGIN_DECLS
and end with __END_DECLS
, which are macros defined in sys/cdefs.h
:
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
The behavior of <fcntl.h>
and <unistd.h>
in C++ is not specified by the standard (because they are also not part of the C89 standard). That said, I have never seen a platform where they (a) exist and (b) actually need to be wrapped in an extern "C"
block.
The behavior of <stdio.h>
, <math.h>
, and the other standard C headers is specified by section D.5 of the C++03 standard. They do not require an extern "C"
wrapper block, and they dump their symbols into the global namespace. However, everything in Annex D is "deprecated".
The canonical C++ form of those headers is <cstdio>
, <cmath>
, etc., and they are specified by section 17.4.1.2 (3) of the C++ standard, which says:
<cassert> <ciso646> <csetjmp> <cstdio> <ctime> <cctype> <climits>
<csignal> <cstdlib> <cwchar> <cerrno> <clocale> <cstdarg> <cstring>
<cwctype>
Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.
So the standard, non-deprecated, canonical way to use (e.g.) printf
in C++ is to #include <cstdio>
and then invoke std::printf
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With