Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extern "C" static void* function

Tags:

c++

After reading about extern and static, I am confused to come across the code which has the line below:

extern "C" static void* foo(int* a){
    return foo1(a);
}

Why does this not generate any error?

like image 321
nineties Avatar asked Jul 18 '16 23:07

nineties


People also ask

Can you extern a static function in C?

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

What is static void function in C?

A static function in C is a function that has a scope that is limited to its object file. This means that the static function is only visible in its object file. A function can be declared as static function by placing the static keyword before the function name.

What is extern void in C?

defines a variable j with external linkage; the extern keyword is redundant here. extern void f(); declares that there is a function f taking no arguments and with no return value defined somewhere in the program; extern is redundant, but sometimes considered good style.

What is extern C in C?

extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block. In a template declaration, extern specifies that the template has already been instantiated elsewhere.


1 Answers

The following also compiles and does the same thing as your line:

extern "C" {
  static void* foo(int* a){
    return foo1(a);
  }
}

The static means that foo() will only be available in file scope, and it overrides the extern "C" when it comes to linkage. Normally, extern "C" effects the name of the function used by the linker if/when it is exported, so that the function could be called from other object files when the entire program is linked. Usually, this is used when either you want to link to an object file built from C source where foo() was defined, or where you want to define foo() so that C code can call it. However, the static causes foo to simply not be exported at all, so it basically doesn't even get a name (it has internal, not external linkage).

extern "C" also has a secondary effect. It also becomes part of the type of foo. That is, C++ code will see foo as having type extern "C" void(int*). Basically, this controls calling convention. A C++ compiler may e.g. arrange arguments differently in registers/on the stack than a C compiler might. Making foo be a C function means that it will use the C conventions and not the C++ conventions. This makes it safe to e.g. pass a function pointer to foo to a C function that expects a pointer to a C function. For example, the standard library has

extern "C" typedef int C_CMP(void const*, void const*);
extern "C++" typedef int CXX_CMP(void const*, void const*);
void std::qsort(void *, std::size_t, std::size_t, C_CMP);
void std::qsort(void *, std::size_t, std::size_t, CXX_CMP);

With the extern "C", &foo is passed to the first overload, but without it/with extern "C++", it is passed to the second. It would not be safe to declare foo without extern "C" and then try to pass it into a C function that expects a pointer to a C function. It would probably work, but it might also break horribly. Add the extern "C" and it becomes correct—you're safe.

like image 194
D Hydar Avatar answered Sep 22 '22 06:09

D Hydar