Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shall external "C" enclose the declaration or definition of a C++ function?

Tags:

c++

c

I saw in a cpp file that external "C" {...} encloses the definitions of several functions.

From https://isocpp.org/wiki/faq/mixing-c-and-cpp, I guess the purpose of using extern "C" in the cpp file is to make the enclosed C++ functions available to be used in a C program.

The example in the link shows that extern "C" encloses the declarations of the C++ functions only, not their definitions

Just declare the C++ function extern "C" (in your C++ code) and call it (from your C or C++ code). For example:

    // C++ code:
    extern "C" void f(int);
    void f(int i)
    {
        // ...
    }

The cpp file I mentioned at the beginning looks like instead:

    // C++ code:
    extern "C" {

    void f(int i)
    {
        // ...
    }

    void g(int i)
    {
        // ...
    }

    }

Shall extern "C" enclose the declarations or definitions of C++ functions? If so, why?

like image 434
Tim Avatar asked Jun 20 '16 16:06

Tim


People also ask

Can we call a function without declaration in C?

A compiler is required to complain if you call a function without declaring it first.

What is declaration and definition of function in C?

A function consist of two parts: Declaration: the function's name, return type, and parameters (if any) Definition: the body of the function (code to be executed)

Does C require function declaration?

Actually, it is not required that a function be declared before use in C. If it encounters an attempt to call a function, the compiler will assume a variable argument list and that the function returns int.

Can you use extern C in C?

By declaring a function with extern "C" , it changes the linkage requirements so that the C++ compiler does not add the extra mangling information to the symbol. This pattern relies on the presence of the __cplusplus definition when using the C++ compiler. If you are using the C compiler, extern "C" is not used.


2 Answers

It should enclose the declarations in the header file, and definitions should be enclosed as long the translation unit is compiled using the c++ compiler, and as long the declaration wasn't seen there.
It's never wrong doing both in c++ code.

If the c compiler is used to compile the function definitions, it's not necessary (or should I better to say would be wrong syntax, see the note below).

extern "C" {} scopes control that plain c symbols linkage is used for everything inside. Otherwise c++ name mangling would be applied.


Note:

Since extern "C" {} this isn't valid c syntax, to make that working with the c compiler, you'll need to use it within #ifdef:

MyHeader.h:

 #ifdef __cplusplus
 extern "C" {
 #endif

 // ... c style function name declarations
 void foo(int i);

 #ifdef __cplusplus
 } // extern "C"
 #endif

The use of the extern "C" {} scope is actually twofold:


Exporting C++ code to C

If the above is compiled with the c compiler, it appears for it as a normal c function declaration. If compiled with the c++ compiler the extern keyword applies and the c++ name mangling will be suppressed.

Regarding the definition, the function can use any c++ features inside it's definition:

 extern "C" {
     void foo(int x) {
         std::vector v(x);
         // ... blah, more c++ stuff
     }
 }

Note that the declaration wasn't included here. This can be used as a technique, particularly useful when you want to override functions exposed from a library for weak linkage.

In case of including the MyHeader.h, the extern "C" {} scope can be omitted.


Importing C code from C++

If the above declaration is seen in the c++ compiler, again c++ name mangling is suppressed, and any call reference to foo() wil be resolved by the linker using a plain c function symbol name:

  #include "MyHeader.h"
  class MyClass {
  public:
       void bar(int y) {
           // Use foo() as plain c function:
           foo(y);
       }
  };

The foo() function implementation is provided from an object file (or archive) that was created using the c compiler.

like image 59
πάντα ῥεῖ Avatar answered Oct 08 '22 16:10

πάντα ῥεῖ


[dcl.link]/5:

Except for functions with C++ linkage, a function declaration without a linkage specification shall not precede the first linkage specification for that function. A function can be declared without a linkage specification after an explicit linkage specification has been seen; the linkage explicitly specified in the earlier declaration is not affected by such a function declaration.

Both versions are fine as far as the language linkage of the function is concerned. The important part is that the first declaration of the function must have extern "C" on it.

like image 31
T.C. Avatar answered Oct 08 '22 17:10

T.C.