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.
foo1 takes a pointer to a C function as shown in [dcl.link] 7.5p4
The example applies directly to
foo1and 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
externand explicit use of a storage specifier is prohibited.As an example of where this difference matters, consider a header containing the following:
Someone might be tempted to change this to:
But that would be incorrect because that converts the declarations into definitions. Instead the correct code using
extern "C" {}is: