extern “C” linkage inside C++ namespace?

2020-02-04 07:28发布

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();
            }
    }
}

标签: c++ c namespaces
2条回答
smile是对你的礼貌
2楼-- · 2020-02-04 07:44

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.

查看更多
冷血范
3楼-- · 2020-02-04 07:55

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

查看更多
登录 后发表回答