C++命名空间内的extern"C"链接?

use*_*438 20 c c++ namespaces

namespace someNameSpace {
    extern "C" void doSomething()
        {
             someOperations();
        }
}
Run Code Online (Sandbox Code Playgroud)

我想doSomething()在C++和C环境中运行.

someNameSpace仍然封装doSomething(),如果我将其暴露在extern "C"联动?

有没有一种很好的方法在C++和C之间共享函数,同时避免在C++端污染全局命名空间?

编辑:因为此代码主要用于C++模式,而C链接仅供测试使用,我想这是一种更好的方法.

namespace someNameSpace {
    #ifdef COMPILE_FOR_C_LINKAGE
    extern "C"
    #else
    extern "C++"
    #endif
    { 
        void doSomething()
            {
                 someOperations();
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 20

你的代码有效,但是你应该注意所有具有extern "C"链接的函数共享相同的名称空间,但是不要与"命名空间"的C++概念混淆:你的函数是真的someNameSpace::doSomething,但你不能有任何其他extern "C"函数doSomething任何其他命名空间中的非限定名称.

见7.5/6:

最多一个具有特定名称的函数可以具有C语言链接.具有相同函数名称的C语言链接的函数的两个声明(忽略限定它的命名空间名称)出现在不同的命名空间范围内引用相同的函数.具有相同名称的C语言链接的变量的两个声明(忽略限定它的命名空间名称)出现在不同的命名空间范围中引用相同的变量.具有C语言链接的实体不得声明与全局范围内的变量同名,除非两个声明都表示同一实体; 如果声明出现在不同的翻译单元中,则无需诊断.具有C语言链接的变量不应声明与具有C语言链接的函数同名(忽略限定相应名称的命名空间名称); 如果声明出现在不同的翻译单元中,则无需诊断.[ 注意:程序中只能出现具有C语言链接的给定名称的实体的一个定义(见3.2); 这意味着不得在多个命名空间范围内定义此类实体.- 结束说明 ]

您公司或项目的全球风格仲裁者应该能够为您的代码库提供合适的命名政策建议.

  • 你在第一段中的最后陈述是错误的 - 你可以在其他命名空间中定义另一个`doSomething`,只要它不是`extern"C"`. (3认同)

小智 9

只是一段代码来说明Kerrek SB答案中陈述的行为

#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;
}
Run Code Online (Sandbox Code Playgroud)

住在http://ideone.com/X26wfR