Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between with braces or without when using extern "C"?

Tags:

c++

So, while being schooled by James Kanze and Loki Astari about C linkage, I was wondering about this:

extern "C" int foo1 (void (*)());
extern "C" { int foo2 (void (*)()); }

After my schooling, I think it must be that foo1 only takes a function pointer with C++ linkage, while foo2 only takes a function pointer with C linkage. Is my understanding correct? Are there specific references in the C++ standard that explain the differences in my example above?

Edit: To make it easier for everyone to follow along here's a pastebin with the relevant part from the C++ 11 draft standard.

like image 847
jxh Avatar asked Aug 08 '12 22:08

jxh


People also ask

When should I use extern C?

The extern must be applied to all declarations in all files. (Global const variables have internal linkage by default.) 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.

Does a while loop need brackets?

The block of code is called the body of the loop and is enclosed in braces and indented for readability. (The braces are not required if the body is composed of only ONE statement.)

Why do I sometimes need to use extern C {} In C++ header files?

The primary use of “extern” in header files is to allow C object modules to be linked into C++ programs. Since the methods of linking between the two languages are very different, one needs to alert a C++ linker that a module was compiled by a C compiler from C source and hence needs C linkage.

Do While loop require curly braces?

In a do-while loop, the do keyword is followed by curly braces { } containing the code statements. Then the condition is specified for the while loop.


2 Answers

foo1 takes a pointer to a C function as shown in [dcl.link] 7.5p4

In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names with external linkage, and variable names with external linkage declared within the linkage-specification. [Example:

extern "C" void f1(void(*pf)(int));
                                                                 // the name f1 and its function type have C language
                                                                 // linkage; pf is a pointer to a C function

The example applies directly to foo1 and the added emphasis highlights what I think is the reason. The function's parameter lists contains a function declarator for a parameter, and all function declarators are affected by the linkage specification. This applies to both braced and non-braced linkage specifications.

Some differences when not using braces are that names are automatically extern and explicit use of a storage specifier is prohibited.

extern "C" int i; // not a definition

int main() {
    i = 1; // error, no definition
}

extern "C" static void g(); // error

As an example of where this difference matters, consider a header containing the following:

extern "C" int a;
extern "C" double b;
extern "C" char c;

Someone might be tempted to change this to:

extern "C" {
    int a;
    double b;
    char c;
}

But that would be incorrect because that converts the declarations into definitions. Instead the correct code using extern "C" {} is:

extern "C" {
    extern int a;
    extern double b;
    extern char c;
}
like image 78
bames53 Avatar answered Sep 21 '22 19:09

bames53


The braces are used when you have many declarations and definitions. Often you can see a start and end in header files for C code to be usable in C++

#ifdef __cplusplus
extern "C" {
#endif

// C stuff here to be available for C++ code

#ifdef __cplusplus
}
#endif

I can recommend reading about "name mangling" http://en.wikipedia.org/wiki/Name_mangling The extern "C" is a key to fallback to C linkage name conventions.

like image 30
epatel Avatar answered Sep 18 '22 19:09

epatel