extern “C” linkage inside C++ namespace?

后端 未结 3 1644
北荒
北荒 2020-12-09 02:41
namespace someNameSpace {
    extern \"C\" void doSomething()
        {
             someOperations();
        }
}

I want to run doSomething(

相关标签:
3条回答
  • 2020-12-09 02:53

    In C++ ABI, namespaces have to be mangled. So this:

    namespace foo
    {
        void bar(int){}
    }
    

    is translated more or less to such symbol:

    foo::bar(int)
    

    When you force the compiler to use C ABI, the similar symbol

    namespace foo
    {
        extern "C" void bazz(int){}
    }
    

    after compilation looks like following:

    bazz
    

    You can see the difference in the godbolt: https://godbolt.org/z/BmVpSQ

    In C ABI there are no namespaces or argument list mangled with the function, so you can only have 1 such symbol in the whole code. Defining it twice:

    namespace foo
    {
        extern "C" void bazz(int){}
    }
    
    namespace foo2
    {
        extern "C" void bazz(int){}
    }
    
    int main()
    {
        foo2::bazz(5);
        return 0;
    }
    

    ...is illegal. Surprisingly to me, gcc doesn't emmit compilation/linking error but runtime error For some reason, gcc compiler emits very strange error:

    https://wandbox.org/permlink/BiN0auna9klBg5GE

    The clang compiler emits just emits simple compilation error in such case:

    https://wandbox.org/permlink/r5CUXm7OKePtG35L

    0 讨论(0)
  • 2020-12-09 03:11

    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

    0 讨论(0)
  • 2020-12-09 03:15

    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.

    0 讨论(0)
提交回复
热议问题