Questions tagged [extern-c]

`extern "C"` is used to indicate that C++ functions and variables should have C linkage instead of C++ linkage, allowing C and C++ modules to interact with each other. The extern-c tag should only be used on C++ questions where the subject of discussion is the behaviour of declarations with 'extern "C"'.

The tag should be used on C++ questions where the subject of discussion is the behaviour of code with extern "C" applied to function declarations.

It should only be used on C++ questions — the tag is mandatory; if the question cannot accept the tag, it should not have the tag either. These questions could be tagged with too, which is generally not a good idea, but these questions are about the interaction with C code. The tag is not required.

extern "C" is used to indicate that C++ functions and variables should have C linkage instead of C++ linkage, allowing C and C++ modules to interact with each other; specifically, it applies C linkage to function types, function names, and variable names.

  • Function types with C linkage represents calling convention, and causes the compiler to use C calling conventions instead of C++ ones (if applicable); this is independent of function names with C linkage. This also allows function pointers to specify whether they point to C or C++ functions.

    typedef void CppFunc();          // void() C++ function type.
    extern "C" typedef void CFunc(); // void() C function type.
    
    CppFunc* cppCppFuncPtr;          // Pointer with C++ linkage, to function with C++ linkage.
    extern "C" CppFunc* cCppFuncPtr; // Pointer with C linkage, to function with C++ linkage.
    CFunc* cppCFuncPtr;              // Pointer with C++ linkage, to function with C linkage.
    extern "C" CFunc* cCFuncPtr;     // Pointer with C linkage, to function with C linkage.
    
  • Function and variable names with C linkage represent name mangling; this is independent of function types with C linkage. C names are subject to minimal or no name mangling, depending on the compiler; the most well-known example of this is MSVC adding calling convention information to C function names, and a leading underscore to C variable names.

Declaring functions as extern "C" allows C++ modules to define functions that can be called from C modules, and C++ modules to connect to functions defined in C modules. Similarly, declaring global or namespace variables as extern "C" allows C++ modules to define variables that can be used in C modules, and C++ modules to connect to variables defined in C modules. [Class member declarations always have C++ linkage, even if the declarations appear inside an extern "C" block.]

extern "C" causes the compiler to treat extern "C" functions and variables as if they were all in the same namespace when compiled, regardless of their actual namespace; two extern "C" function declarations with the same unqualified name, or two extern "C" variables with the same name, always refer to the same entity, regardless of whether they're in the same namespace or not. Similarly, an extern "C" function cannot have the same name as an extern "C" variable, regardless of whether they're in the same namespace or not. In effect, it applies the C compiling algorithm to the declaration instead of the C++ algorithm, generating a symbol identical to if the function or variable was in a C module.

extern "C" functions are allowed to contain C++ code within them, and will execute properly even if called from C code.

For more information on linkage and extern "C", see the cppreference page

79 questions
4
votes
4 answers

Problem with using C code in C++ with extern "C"

I know when i want to link C code as C code in C++ should i use extern "C". But with the following code : /* file.h */ some (void) { return 10; } extern "C" { #include "file.h" } #include int main (void) { std::cout <<…
Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32
4
votes
1 answer

Are extern extern "C", and extern "C" extern, allowed?

Is this code correct? extern "C" extern int x; // 1 extern extern "C" int y; // 2 extern "C" extern "C" int z; // 3 int main() { } gcc rejects 1 and 2 as syntax errors and accepts 3. clang accepts all three but gives a…
M.M
  • 138,810
  • 21
  • 208
  • 365
4
votes
1 answer

Link to Fortran library (Lapack) from C++

I'm using Lapack in my C++ code. I'm quite confused how to properly link to the library. Here is a small example corresponding to my code calling a function from Lapack: #include namespace lapack { extern "C" { void ilaver(int* major,…
Caduchon
  • 4,574
  • 4
  • 26
  • 67
4
votes
0 answers

Generic lambda in extern "C" function

Following code is accepted by gcc 6 and clang 4, but MSVC 2017 which claims to support C++14 (and generic lambdas in particular) discards it with error C2894: templates cannot be declared to have 'C' linkage extern "C" void f() { …
rafalc
  • 203
  • 5
  • 9
4
votes
1 answer

Does it make sense to use _attribute__ ((nothrow)) inside extern C?

I have some C code being called from C++. The header resembles the following: #ifndef CLibH #define CLibH #ifdef __cplusplus extern "C" { #endif //C API void foo(void); // ... #ifdef __cplusplus } #endif #endif Since I'm already using extern…
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
4
votes
1 answer

error: expected unqualified-id on extern "C"

I have a cpp code in which I want to call a c function. Both compile well to .o files, but when the clang++ is executing for compilation, I receive the following error: file.cpp:74:12: error: expected unqualified-id extern "C" ^ The…
Laurent Crivello
  • 3,809
  • 6
  • 45
  • 89
3
votes
2 answers

One-liner extern "C" for a variable - legit?

Consider the following translation unit: extern "C" int x = 1; I know that C-mangling an int doesn't mean much; and that int x = 1 already guarantees external linkage, but this should work. Which it does; the thing is, GCC warns about using it,…
einpoklum
  • 118,144
  • 57
  • 340
  • 684
3
votes
1 answer

Using lambda for callback function as C function parameter

I was writing my own std::thread-like wrapper for pthread_* functions (for educational purposes). The constructor I came up with looked like this: template explicit Thread(Fn&& fn, Args&&... args) { using Invoker =…
Evg
  • 25,259
  • 5
  • 41
  • 83
3
votes
2 answers

To extern "C" or Not to extern "C" [g++ vs cl]

I'm comparing Numerical Recipes four1.c to Nayuki's FFT. Both are the C versions, but I'm using a C++ driver. For the comparison, I'm compiling (or more appropriately, linking) both into an executable with CL.exe and g++. The two appear to be…
KyleG
  • 143
  • 7
3
votes
2 answers

Cannot Call C++ Code from C without Error

I'm trying to write a C++ library that can be called from C. However, whenever I try to even write a bare minimum example, it crashes with undefined references. Here is my code: mylibrary.h #ifndef __MY_CPP_THING_H #define __MY_CPP_THING_H #ifdef…
Griffort
  • 1,174
  • 1
  • 10
  • 26
3
votes
2 answers

Why does Visual Studio fail to give an undefined reference error when extern "C" is specified?

Given this code: A2.H _declspec(dllimport) void SomeFunc(); struct Foo { Foo(); ~Foo(); }; inline Foo::Foo() { } inline Foo::~Foo() { SomeFunc(); } A1.H #include "A2.h" extern "C" void TriggerIssue(); // <-- This! extern "C" inline…
ForeverLearning
  • 6,352
  • 3
  • 27
  • 33
3
votes
0 answers

extern c linkage errors in visual studio

I have a simple c++ Visual Studio project: #include "test.h" test::test() { } test::~test() { } HEADER: #pragma once #include class test { public: test(); ~test(); }; When I compile test.cpp I get many errors in the vc/include…
PatMac
  • 79
  • 9
3
votes
1 answer

unknown attribute `extern_c` warning in C++

I’m building a Cocos2d-x game for Android on a Mac, using Android NDK, and I get many warnings like this when compiling the C++ part: /usr/include/module.map:1662:22: warning: unknown attribute 'extern_c' [-Wignored-attributes] Is it dangerous? How…
DavidGuaita
  • 501
  • 1
  • 7
  • 18
2
votes
2 answers

If I declare a function with extern "C", should I also define it that way?

In my header file, foo.h, I have: #ifdef __cplusplus extern "C" { #endif int foo(int x); #ifdef __cplusplus } #endif Now, in foo.cpp, should I also use extern "C", and define: #include "foo.h" extern "C" { int foo(int x); }; ? Or is the…
einpoklum
  • 118,144
  • 57
  • 340
  • 684
2
votes
3 answers

Using a enum class from a c++ header in a c header

I am writing a c wrapper around a c++ library. In the c++ there are enum classes used as types for function arguments. How do I use theme correctly in the c header. One ugly way would be to use int's in the c function and cast theme in the wrapper…
ludw
  • 113
  • 8