c++ - Best Practise and Semantics of namespace nested functions and the use of extern "C" -
i creating c++ library c-abi interface.
this how gcc treats extern "c" qualifier regards mangling:
namespace x { extern "c" int monkey(int x) { return 1; } int chimpanzee(int x) { return 1; } }
the relevant nm
output:
00000000004005cd t _zn1x10chimpanzeeei 00000000004005bf t monkey
question: want leave functions involved in c-abi inside namespace, maximum flexibility reuse. important note: once library has been compiled give linker map file (gcc) or module definition file (msvc).
- is mangling output standard behaviour -- other major compilers (msvc in specific) strip mangling ?
- are pitfalls or best-practises regarding placing functions in name-space when involved in external abi?
- will interfere c-abi export of de-mangled functions during link time ?
this msvc.
the namespace not name-mangled, name of namespace incorporated in function's (or object's) name when name mangling occurs. process undocumented, described here.
answering specific questions jumping around:
1) there no standard-defined behavior regarding name mangling. standard says implementations provides c-compatible linkage extern "c"
constructs:
7.5.3 [linkage specifications]
every implementation shall provide linkage functions written in c programming language, "c", , linkage c + + functions, "c++". [example:
complex sqrt(complex); // c + + linkage default extern "c" { double sqrt(double); // c linkage }
—end example]
ultimately means since c has no concept of namespace
s, if extern "c"
functions or objects in namespaces, exported names lose namespace qualification. leads to...
3) yes, can have linkage problem. try this:
main.h
#ifndef main_api # define main_api __declspec(dllexport) #endif namespace x { extern "c" main_api void foo(); }; namespace y { extern "c" main_api void foo(); };
main.cpp
#include <cstdlib> #include <iostream> using namespace std; #define main_api __declspec(dllexport) #include "main.h" void x::foo() { cout << "x::foo()\n"; } void y::foo() { cout << "y::foo()\n"; } int main() { }
this emit linker error because extern "c"
-ed versions of x::foo()
, y::foo()
have lost namespace identification, end same name: foo()
2) best practices regarding this. if must export c-abi functions in namespaces, have careful names end exporting not same. degree, defeats purpose of using namespace
in first place. can this:
#ifndef main_api # define main_api __declspec(dllexport) #endif namespace x { extern "c" main_api void x_foo(); }; namespace y { extern "c" main_api void y_foo(); };
Comments
Post a Comment