可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
namespace someNameSpace { extern "C" void doSomething() { someOperations(); } }
I want to run doSomething()
in both C++ and C environment.
Is someNameSpace
still encapsulating doSomething()
if I expose it to extern "C"
linkage?
Is there a good way to share functions between C++ and C while avoiding polluting global namespace on C++ side?
Edit: Because this code is primarily used in C++ mode, while the C linkage is for test use only, I guess this is a better way to do it.
namespace someNameSpace { #ifdef COMPILE_FOR_C_LINKAGE extern "C" #else extern "C++" #endif { void doSomething() { someOperations(); } } }
回答1:
Your code works, but you should beware that all functions that have extern "C"
linkage share the same space of names, but that is not to be confused with the C++ notion of "namespace": Your function is really someNameSpace::doSomething
, but you cannot have any other extern "C"
function with unqualified name doSomething
in any other namespace.
See 7.5/6:
At most one function with a particular name can have C language linkage. Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function. Two declarations for a variable with C language linkage with the same name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same variable. An entity with C language linkage shall not be declared with the same name as a variable in global scope, unless both declarations denote the same entity; no diagnostic is required if the declarations appear in different translation units. A variable with C language linkage shall not be declared with the same name as a function with C language linkage (ignoring the namespace names that qualify the respective names); no diagnostic is required if the declarations appear in different translation units. [Note: Only one definition for an entity with a given name with C language linkage may appear in the program (see 3.2); this implies that such an entity must not be defined in more than one namespace scope. ― end note]
Your company's or project's global style arbiters should be able to advise you on a suitable naming policy for your code base.
回答2:
Just piece of code to illustrate behavior stated in Kerrek SB answer
#include <iostream> namespace C{ void Hello(){ std::cout<<"Hello"<<std::endl; } extern "C" void HelloThere(){ std::cout<<"Hello There from extern \"C\""<<std::endl; } } extern "C" void HelloThere(); int main() { C::Hello(); C::HelloThere(); //Compiles //Hello(); <--- does not compile HelloThere(); //Also compiles and prints the same as C::HelloThere() !!! return 0; }
Live at http://ideone.com/X26wfR