The _
prefix is a result of name mangling, which depends on the target platform ABI (OS, bitness, calling convention).
According to Microsoft, the _
prefix is used in a 32-bit Windows cdecl
calling convention, but not in 64-bit (source):
Format of a C decorated name
The form of decoration for a C function depends on the calling convention used in its declaration, as shown in the following table. This is also the decoration format that is used when C++ code is declared to have extern "C" linkage. The default calling convention is __cdecl. Note that in a 64-bit environment, functions are not decorated.
Calling convention — Decoration
__cdecl
Leading underscore (_
)
__stdcall
Leading underscore (_
) and a trailing at sign (@
) followed by the number of bytes in the parameter list in decimal
__fastcall
Leading and trailing at signs (@
) followed by a decimal number representing the number of bytes in the parameter list
__vectorcall
Two trailing at signs (@@
) followed by a decimal number of bytes in the parameter list
The reason behind could be that 32/64-bit Windows calling conventions aren't really compatible. For example, function arguments in 64-bit mode are passed differently and different registers have to be preserved between calls.
Anyway, to answer the question, I can think of a couple of workaround solutions:
Solution 1
The code that generates the .asm
should add the leading _
only in 32-bit mode (the generated assembly will probably have to differ in other ways too, especially if pointers are involved).
Solution 2
Use a preprocessor to add the leading _
in 64-bit mode:
#ifdef _WIN64
# define foo _foo
#endif
extern "C" int foo(void);
int main()
{
int x = foo();
return 0;
}