tags:

views:

268

answers:

5

As we know that we can use c functions directly in c++, when is extern "C" necessary then?

+9  A: 

It's necessary when a C++ function must be called by C code rather than C++ code.

Basically, when you want your C++ library to be backwards compatible.

Randolpho
No, no, no ... ugh! If a project is `C`, don't add `C++` to it: convert it to `C++` and, if needed, add `C` to the `C++` project. *Or (even better IMHO) keep it in `C` and avoid `C++` altogether.*
pmg
This answer is correct but incomplete, like the answer by @Graham Perks, which is also correct but incomplete. The whole answer would be the sum of both.
David Rodríguez - dribeas
@pmg: you may not own the C Project or be able to change the interface they desire even if your library is developed in C++
Greg Domjan
@pmg: think external libraries and callbacks.
Potatoswatter
@pmg: why not avoid C altogether and just [program with butterflies](http://xkcd.com/378/)?
Randolpho
@pmg: -1 to your comment if that were possible
Falmarri
I tried butterflies: it takes too long. And yes, life isn't fair and you're forced to do the wrong thing now and then. When that happens, `extern "C"` is good.
pmg
Or when you want to use your function in a DLL. Since the C++ name decorating rules are not stable across versions of the compiler or across compilers, you cannot export C++ names from a DLL and expect them to work reliably (across multiple versions and multiple compilers).
Larry Osterman
+12  A: 

If your function is implemented in a .c file, the .cpp files will need the extern "C" reference, or else they'd reference a mangled C++-style function name, and the link would fail.

It's also handy for exporting functions from DLLs so that they are exported with a non-mangled name.

Graham Perks
This answer is correct but incomplete, like the answer by @Randolpho, which is also correct but incomplete. The whole answer would be the sum of both.
David Rodríguez - dribeas
+3  A: 

Because the function signatures generated by C and C++ compilers differ -- this sets up the C convention for C function even when using C++.

Dirk Eddelbuettel
+4  A: 

As you know that c++ support function overloading, which define the same function or method many times with different parameters. To do this, the compiler has to add some part of symbols for each one ... for example, the compiler will change the function name foo in the following declaration from

void foo(int f,char c);

to

foo@i&c

Unfortunately, C doesn't support this. All function names remain the same after compiling it. So, to call a c++ function from c, you have to know the exact name after the modification and I think it's hard and different from a compiler to another.

to work around this and be able call c++ function from c and stop the compiler from changing the names you have to use this keyword like

extern "C" { 
void foo(int f,char c);
}

that's it !!!

Bander
+1 For explaining the reasons clearly, but this occurs also in the opposite direction: If you have a function in C in a library, and you include the header without the `extern "C"` qualifier, the c++ compiler will mangle the symbol. Then at link stage it will try to locate the mangled symbol and will fail to do so, as the c compiler did not mangle the name while compiling the C code.
David Rodríguez - dribeas
+7  A: 

There are two rather different uses for extern "C". One is to define a function in C++ that you should be able to call from C. I.e., you're writing code in C++, but it needs to interface with C code. In this case, you define the function as extern "C":

extern "C" {
    int c_callable_func1() {}
    int c_callable_func2() {}
}

When you do this, the interface of those functions must follow pretty much the same rules as they would in C as well (e.g., you can't overload the functions or use default values for any parameters).

The other (considerably more common) situation is that you have code written in C that you want to be able to call from C++. In this case, the function definitions remain exactly as before, but the functions need to be declared/prototyped as extern "C". In a typical case, you want to use a single header that can be #included in either a C or C++ file, so the structure looks something like this:

// myheader.h
#ifndef MY_HEADER_H_INCLUDED_
#define MY_HEADER_H_INCLUDED_

#ifdef __cplusplus
extern "C" {
#endif

    int func1(void);
    void func2(int);

#ifdef __cplusplus
}
#endif

#endif

So, a C++ compiler will see function declarations (and typedefs, etc.) surrounded by an extern "C" block, while a C compiler will see prototypes, not surrounded by something it doesn't recognize.

In the first case (C++ functions callable from C), you'll normally structure the header roughly the same way, so you can also call those functions from C++ if necessary (but at the interface, you still lose all extra features of C++ like function overloading).

Jerry Coffin