How does C's “extern” work?

后端 未结 7 1467
轻奢々
轻奢々 2020-12-28 10:56

I have a C/C++ program that\'s a plugin to Firefox. Because it\'s a plugin, it has non-main entry points. Those entrypoints need to be compiled in C because otherwise they g

相关标签:
7条回答
  • 2020-12-28 11:28

    You seem to be overly obsessed with this "putting around"/"wrapping" thing. At the fundamental level you are not normally supposed to put extern "C" "around" anything. extern "C" is a declaration specifier, a linkage specifier, which assigns C-linkage to a specific name. Again, it applies to specific individual names. At the fundamental level you are supposed to declare each of your C++-to-C interface functions in your header file as extern "C", as in

    extern "C" void foo(void);
    extern "C" char bar(int);
    

    Later you can specify the same extern "C" to the function definitions in the implementation file

    extern "C" void foo(void) {
      /* whatever */
    }
    
    extern "C" char bar(int) {
      /* whatever */
    }
    

    But strictly speaking, it is not really necessary to repeat extern "C" in the definition, since if you have already declared your function as extern "C", this linkage specification basically gets "inherited" by the definition as well (assuming the declaration is made before the definition in this translation unit). In other words, these function names will not get "mangled", since the compiler knows already, that these names are declared as extern "C" names.

    That's all there's to it. Now, as you already know, you can also use a {} form of extern "C" that lets you wrap the entire section of a file into the extern "C" region. Well, that's just a nice side-feature of extern "C" that can save you some typing. But normally, you should not just indiscriminately enclose entire files into the extern "C" region - this is akin to shooting sparrows with a cannon. The specifier is supposed to be applied selectively, only to the names that really need C-linkage. Actually, in many cases you might (and will) have a dedicated C-interface header file that contains only declarations that are supposed to have C-linkage. Putting the extern "C" around the entire header file in this case is normal practice, but in general case you should use it more carefully and make sure you are not covering with a blanket extern "C" specifier something that is not supposed to have C-linkage.

    0 讨论(0)
  • 2020-12-28 11:30

    This is not a kludge - this is how C/C++ compilers work. When the compiler compiles a file that uses your library, it checks the .h files for declarations of functions and globals. Hence, you wrap the .h files with extern "C" to avoid name mangling.

    0 讨论(0)
  • 2020-12-28 11:31

    if the .c file includes the .h file and the function prototypes in the .h file are in an extern "C" block, everything should be ok. The functions declared as extern "C" won't have mangled names, all the other functions will.

    0 讨论(0)
  • 2020-12-28 11:33

    Only the declaration of the functions needs to be wrapped in extern "C". Once the function has been declared, the compiler knows that its name shouldn't be mangled. Since most of the time your function declarations are in your header file, wrapping the extern "C" around your header or around the include of it should work fine.

    0 讨论(0)
  • 2020-12-28 11:35

    It is already enough when you only extern "C" the entities you need to be externally visible. You can make a standard cc/cpp/cxx/... file, but cherry pick C-names:

    class Foo {};
    
    extern "C" int someInterfaceFun () {
        Foo foo;
        return 0xFEED;
    }
    
    0 讨论(0)
  • 2020-12-28 11:43

    Extern "C" should apply to function prototype, so if you have separate prototype and implementation, put extern declaration around prototypes. Implementation, provided prototype is visible, will be extern as well and not mangled. It is not a bug.

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