Handmade Hero»Forums»Code
Vivek
9 posts
doubt, Why are we using extern "c"??
Hi,

I am at day 030 and this is the question I have,

We are using extern "C" in handmade.cpp for two funtions that gets called from
the platform layer, I know this is to avoid name mangling, but why? (even if extern "C" is removed everything works fine). Need some clarification...
Mārtiņš Možeiko
2565 posts / 2 projects
doubt, Why are we using extern "c"??
Edited by Mārtiņš Možeiko on
It appears Visual Studio linker exports unmangled function name if it is specified with /EXPORT command-line argument (which is what build.bat does in Handmade Hero build).

In such case there is really no need for extern "C".

The documentation is very vague about this:
/EXPORT:entryname
...
LINK uses decorated forms of identifiers. The compiler decorates an identifier when it creates the .obj file. If entryname is specified to the linker in its undecorated form (as it appears in the source code), LINK attempts to match the name. If it cannot find a unique match, LINK issues an error message.
So I can understand the reason to use extern "C" to guarantee that name will not be mangled.
Vivek
9 posts
doubt, Why are we using extern "c"??
Basically you are saying that extern "C" will guarantee (non mangled function names) on all compilers,linkers.
But I am asking why are we trying to unmangle and what is wrong with mangling, are we trying to make sure that those specific functions cannot be overloaded if so why?(any specific reasons?)
Mārtiņš Možeiko
2565 posts / 2 projects
doubt, Why are we using extern "c"??
Edited by Mārtiņš Možeiko on
Yes, that's the purpose of extern "C" - to make function be "C compatible". And to do that you are not allowed to mangle the name. C functions are not mangled. If function "foo" will be mangled in C++ file, and you'll want to call it from C code which only knows unmangled name, then linker won't be able to connect those two.

We want to have unmangled name, because we don't know what will be mangled name. It is not standartized. Every compiler is free to do mangling in whatever way they want. MSVC mangling is completely different from GCC one (clang supports both). Why that's a problem? Because we need to specify function name to look up in dll for GetProcAddress as a string. If we don't know the name, how can we look up the function? You could do that by index, but that is also arbitrary and needs to be fixed with /EXPORT argument - so not really an advantage over unmangled name.
Vivek
9 posts
doubt, Why are we using extern "c"??
Thanks for the clarification.

we are doing this just because GetProcAddress could not handle mangled names
(^ leaving this here, for others)
Mārtiņš Možeiko
2565 posts / 2 projects
doubt, Why are we using extern "c"??
Almost, but not exactly. GetProcAddress handle mangled names correctly. The problem is that it is very "dumb" - it does simple string compare to find exported function.

If you know mangled name, you can easily lookup the function with GetProcAddress. For example, function like "int foo(float, const char*)" with MSVC mangled name would look like: "?foo@@YAHMPBD@Z". If you pass this string to GetProcAddress, it will find the function.

So if you like doing additional work and find mangled names for dll file yourself (dumpbin utility can help you), then you can use them in win32 layer for GetProcAddress just fine.