简体   繁体   中英

C++ assign function in order to re-export it as extern “C”

Is it possible to export a C++ function with a C-compatible type (in this case (int, int) -> int ) as a C symbol just by assigning it? Are there any hidden gotchas you have to watch out for?


The following code compiles without warnings and the resulting file has two symbols exposed.

I was surprised that it compiles at all, since I'm not sure what it means to copy a function.

namespace simplemath {
  int add(int x, int y) {
    return x + y;
  }
}

extern "C" auto add = simplemath::add;

$ clang++ -Wall -Werror -pedantic --std=c++11 -c example.cc
$ nm example.o
0000000000000000 T __ZN10simplemath3addEii
0000000000000018 D _add

Is the code above equivalent to the following (up to whether or not simplemath::add is inlined)?

extern "C" int add(int x, int y) {
  return simplemath::add(x, y);
}

namespace simplemath {
  int add(int x, int y) {
    return x + y;
  }
}

You get

$ clang++ -Wall -Werror -pedantic -c example.cc
$ nm example.o
0000000000000020 T __ZN10simplemath3addEii
0000000000000000 T _add

No, this won't, in general, work. Functions with C linkage and functions with C++ linkage have different types, even if they take the same argument types and return the same type. So that function-pointer assignment is not legal. Most compilers don't enforce this, however, so you might get away with it. Of course, as soon as you upgrade to a compiler that enforces the correct semantics here your code will break.

Many people misunderstand the difference between C and C++ linkage, and think that it's just a matter of name mangling. But it's more than that. For example, the compiler can use different calling conventions for the two different linkages, and in that case, there's no way you could use a pointer to a C++ function in C code. extern "C" tells the compiler to compile the function so that it can be called from C.

The first version doesn't really copy a function (you can't do that), but rather creates a pointer to the function.

That might perhaps work if the compiler uses the same calling conventions for C and C++ functions. It might fail to compile otherwise, I don't know.

Anyway, I would use the second version as that is the intended way to create wrapper functions, and will be more portable. By "repacking" the parameters in the extern "C" function we know that they are passed correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM