Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static vs extern "C"/"C++"

Tags:

What is the difference between a static member function and an extern "C" linkage function ? For instance, when using "makecontext" in C++, I need to pass a pointer to function. Google recommends using extern "C" linkage for it, because "makecontext" is C. But I found out that using static works as well. Am I just lucky or...

class X {    public:    static void proxy(int i) {} } makecontext(..., (void (*)(void)) X::proxy, ...); 

vs

extern "C" void proxy(int i) {} makecontext(..., (void (*)(void)) proxy, ...); 

EDIT: Can you show a compiler or architecture where the static member version does not work (and it's not a bug in the compiler) ?

like image 388
Giovanni Funchal Avatar asked Feb 26 '09 19:02

Giovanni Funchal


People also ask

Can static function extern in C?

Static variables in C have the following two properties: They cannot be accessed from any other file. Thus, prefixes “ extern ” and “ static ” cannot be used in the same declaration. They maintain their value throughout the execution of the program independently of the scope in which they are defined.

What is auto static and extern in C?

auto is used for a local variable defined within a block or function. register is used to store the variable in CPU registers rather memory location for quick access. Static is used for both global and local variables. Each one has its use case within a C program. Extern is used for data sharing between C project files ...

Can I extern a static function?

You cannot use extern and static together they are mutually exclusive. You need to use only extern if you need External Linkage.

Is extern necessary in C?

You do not necessarily "need" extern for variables. When C was invented Unix linkers were also written, and they advanced the art in unheralded but clever ways. One contribution was defining all symbols as small "common blocks".


2 Answers

Yes, you are just lucky :) The extern "C" is one language linkage for the C language that every C++ compiler has to support, beside extern "C++" which is the default. Compilers may supports other language linkages. GCC for example supports extern "Java" which allows interfacing with java code (though that's quite cumbersome).

extern "C" tells the compiler that your function is callable by C code. That can, but not must, include the appropriate calling convention and the appropriate C language name mangling (sometimes called "decoration") among other things depending on the implementation. If you have a static member function, the calling convention for it is the one of your C++ compiler. Often they are the same as for the C compiler of that platform - so i said you are just lucky. If you have a C API and you pass a function pointer, better always put one to a function declared with extern "C" like

extern "C" void foo() { ... } 

Even though the function pointer type does not contain the linkage specification but rather looks like

void(*)(void) 

The linkage is an integral part of the type - you just can't express it directly without a typedef:

extern "C" typedef void(*extern_c_funptr_t)(); 

The Comeau C++ compiler, in strict mode, will emit an error for example if you try to assign the address of the extern "C" function of above to a (void(*)()), beause this is a pointer to a function with C++ linkage.

like image 135
Johannes Schaub - litb Avatar answered Oct 04 '22 16:10

Johannes Schaub - litb


Note, that extern C is the recommended way of C/C++ interoperability. Here is the master talking about it. To add to eduffy's answer: note that static functions and variables in the global namespace are deprecated. Use an anonymous namespace at least.

Back to extern C: if you don't use extern C you will have to know the exact mangled name and use it. That is much more of a pain.

like image 29
dirkgently Avatar answered Oct 04 '22 16:10

dirkgently