Do I need an extern “C” block to include standard POSIX C headers?

前端 未结 6 1819
一向
一向 2020-11-29 11:21

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

相关标签:
6条回答
  • 2020-11-29 11:35

    It is a good idea to let the compiler know so that it can expect C code when compiling as C++. You might also find that the header files themselves contain extern "C" { as guards.

    For example, curses.h on my system contains:

    #ifdef __cplusplus
    extern "C" {
    ...
    
    0 讨论(0)
  • 2020-11-29 11:40

    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
    
    0 讨论(0)
  • 2020-11-29 11:46

    No, you should use the C++ wrapper headers (for instance like <cstdio>). Those take care of all that for you.

    If it's a header that doesn't have those, then yes, you'll want to wrap them in extern "C" {}.

    ETA: It's worth noting that many implementations will include the wrapper inside the .h file like below, so that you can get away with not doing it yourself.

    #ifdef  __cplusplus
    extern "C" {
    #endif
    
    #ifdef  __cplusplus
    }
    #endif
    
    0 讨论(0)
  • 2020-11-29 11:49

    I just double checked the stdlib.h for the GNU compiler and the declarations do not use extern "C" as declarations.

    edit:

    if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES
    define __BEGIN_NAMESPACE_STD    namespace std {
    

    So including the old headers will place declarations on std provided _GLIBCPP_USE_NAMESPACES is defined?

    0 讨论(0)
  • 2020-11-29 11:51

    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.

    0 讨论(0)
  • 2020-11-29 11:52

    Yes, you do. However, many systems (notably Linux) are already adding an extern "C" bracketing like you do. See (on Linux) files /usr/include/unistd.h /usr/include/features.h and the macro __BEGIN_DECLS defined in /usr/include/sys/cdefs.h and used in many Linux system include files.

    So on Linux, you usually can avoid your extern "C" but it does not harm (and, IMHO, improve readability in that case).

    0 讨论(0)
提交回复
热议问题