How can i avoid name mangling? - c++

How can I avoid name mangling in C++?

You can't. It's built into compilers to allow you overloading functions and to have functions with the same name in different classes and such stuff. But you can write functions that are mangled like C functions. Those can be called from C code. But those can't be overloaded and can't be called by "normal" C++ function pointers:
extern "C" void foo() {
}
The above function will be mangled like C functions for your compiler. That may include no change at all to the name, or some changes like a leading "_" in front of it or so.

Other way:
Controlling Names Used in Assembler Code (gcc spec.)
You can specify the name to be used in the assembler code for a C function or variable by writing the asm (or __asm__) keyword after the declarator. It is up to you to make sure that the assembler names you choose do not conflict with any other assembler symbols, or reference registers.
To specify the assembler name for functions, write a declaration for the function before its definition and put asm there, like this:
int func () asm ("MYFUNC");
int func ()
{
g++ will compile it and nm -D output will be
0000000000001e02 T MYFUNC
instead of
0000000000001e02 T _Z4funcv
Tested on g++ 4.9.2

You mean so you can export your function from a library?
extern "c" { your code here }

Schaub's answer is factually incorrect. The most common reason to avoid name mangling is because you are building a shared library (on Windows, a DLL) that is used by client software you don't control that expects certain exported function names. Because of mangling differences between compilers, such interfaces have historically avoided name mangling.
What you have to do is this. First, in your source code prepend extern "C" to get rid of C++ mangling; this still leaves C mangling though. Second, use the -Wl,--kill-at command line option when compiling.
Example:
extern"C" __declspec(dllexport) hresult __stdcall MyExportedFunction( ... )
{
....
}
And compile with:
gcc -shared -mwindows -Wl,--kill-at -Werror ... -o MyLib.dll MyLib.cpp -lkernel32 -l...
You can verify whether you got it right using Dependency Walker.

If you want to compile to wasm you can add the --demangle option to the wasm-ld linker via clang -Wl,--demangle

Related

I receive different results on UNIX and WIN when use static members with static linking of shared library to executable. Please explain why?

Please consider following peace of code:
// 1. Single header file. Imagine that it is some static library.
// Counter.h
#pragma once
struct Counter
{
Counter()
{
++getCount();
}
static int& getCount()
{
static int counter = 0;
return counter;
}
};
// 2. Shared library (!) :
// main_DLL.cpp
#include <iostream>
#include "counter.h"
extern "C"
{
__declspec(dllexport) // for WIN
void main_DLL()
{
Counter c;
std::cout << "main_DLL : ptr = " << &Counter::getCount()<< " value = " << Counter::getCount() << std::endl;
}
}
// 3. Executable. Shared library statically (!) linked to the executable file.
// main.cpp
#include "counter.h"
#include <iostream>
extern "C"
{
__declspec(dllimport) // for WIN
void main_DLL();
}
int main()
{
main_DLL();
Counter c;
std::cout << "main_EXE : ptr = " << &Counter::getCount() << " value = " << Counter::getCount() << std::endl;
}
Results:
Results for WIN (Win8.1 gcc 5.1.0):
main_DLL : ptr = 0x68783030 value = 1
main_EXE : ptr = 0x403080 value = 1
// conclusion: two different counters
Results for UNIX (Red Hat <I don’t remember version exactly> gcc 4.8.3):
main_DLL : ptr = 0x75693214 value = 1
main_EXE : ptr = 0x75693214 value = 2
// conclusion: the same counter addressed
Building:
Building for WIN:
g++ -c -Wall -Werror -o main_DLL.o main_DLL.cpp
g++ -shared -Wl,--out-implib=libsharedLib.a -o libsharedLib.so main_DLL.o
g++ -Wall –Werror -o simpleExample main.cpp -L./ -lsharedLib
Building for UNIX:
g++ -c -Wall -Werror -fPIC -o main_DLL.o main_DLL.cpp
g++ -shared -fPIC -o libsharedLib.so main_DLL.o
g++ -Wall –Werror -fPIC -o simpleExample main.cpp -L./ -lsharedLib
So, you see that I added –fPIC on UNIX and there is no need to create import library for UNIX, because all exports symbols are included inside shared library. On Windows I use __declspec for it.
For me, results on Windows are pretty much expected. Because shared library and executable are building separately and they should know about static variable in Counter::getCount. They should simply allocate memory for it, that’s why they have different static counters.
I did quite some analysis using tools like nm, objdump. Although I’m not a big expert in them, so I haven’t found anything suspicious. I can provide their output if needed.
Using ldd tool I can see that library linked statically in both cases.
Why I can’t see the same results on Unix for me it’s strange. Could the root cause lie in building options (–fPIC, for example), or I’m missing something?
In windows, A DLL is not exporting global and static symbols unless you add the dllexport statement, therefore, the linker doesn't even know they exists, so it allocate new instance for the static member.
In linux/unix a shared lib is exporting all the global and static symbols, so when the linker find the existence of the static member in the shared lib, it just use its address.
That is the reason for the different result.
EDIT: This is a complete rewrite of the answer. With much more details.
I think that this question deserves more elaborated answer. Especially that there are things that were not mentioned so far.
Dependency Walker
Let me start with referring to the “Dependency Walker” program.
It is a nice program (although these days a bit old-schoolish in its look & feel) that allows analyzing Windows binaries (both EXE and DLL) for symbols that they export/import and their own dependencies to other DLLs. Also it allows showing undecorated symbol names but this seems to be working only with MSVC build binaries. (And some more but that is not important here.)
Thanks to this program crucial information (for this question) can be uncovered. So I encourage you to use it during experiments.
Exporting policy on Linux vs. Windows
SHR already pointed this out but I will mention it also for completeness of the answer. And some extra details.
On Linux every symbol gets exported from a shared library by default. On the other hand on Windows you have to explicitly state which symbols to export from a shared library.
GCC seems however to provide some means of controlling exports in "Windows style". See for example Visibility entry on GCC Wiki.
Also note that there are various ways of exporting on both Linux and Windows. For example both seem to support exporting selectively by providing linker with a list of names for symbols to export. But it also seems that nowadays (on Windows at least) this isn't really used much. __declspec approach seems to be preferred.
What can be exported?
After that general introduction let's now stick to Windows case. Nowadays you export/import symbols from shared libraries by using the __declspec. Just as shown in the question. (Well maybe not exactly that - typically you use a #define to handle bi-directionality as shown in already mentioned Visibility entry on GCC Wiki.)
But the declaration can be applied not only to functions, methods and global variables. It can also be applied to types. For example you can have:
class __declspec(dllexport) Counter { /* ... */ };
Such exporting/importing means in general that all members get exported/imported.
Not so easy!
But it would be too easy, wouldn't it? The complication is that GCC and MSVC handle exporting types differently.
My notes here are based mostly on experiments (checks done using Dependency Walker) so I can be wrong or not precise enough. But I did observe differences in behavior.
In tests I used MSVC 2013 from the Express Edition with update 5. For GCC I used MinGW distro from nuwen.net, version 13.0.
MSVC, when exporting entire type, exports each and every member. Including implicitly defined members (like compiler generated copy constructor). And including inlined functions. Furthermore if inlined function has some static local variables they get exported to (!).
GCC on the other hand seems to be far more restrictive. It doesn't export implicitly defined members. Nor it doesn't export inlined members.
Exporting/Importing inline functions
If instead of exporting entire type you would explicitly export an inlined function then and only then will GCC really export it. But still it will not export static local variables in that function.
Further more if you try to import an inlined function GCC will error. With GCC you cannot define symbols that you are importing. And this happens when you import inlined (and so defined) symbol. So in fact it doesn't make any sense to export inlined functions with GCC.
MSVC allows to import inlined functions. In all cases I checked it didn't seem to actually inline the function but instead called the imported version.
Yet note that because MSVC in case of inlined function exports also its static local variables it would be possible for it to really inline the function (rather than import it) while maintaining a single copy of static local variables. For ordinary programs such behavior is mandated by the Standard (N3337, C++11), in point 7.1.2 ([dcl.fct.spec]) at $4 we can read:
(…) A static local variable in an extern inline function always refers to the same object. (…)
But a program and a shared library are actually more like two programs so they are out of scope for the Standard. Yet MSVC even in that case acts (or better to say: could act) as one would expect from a single program.
Solution
Denis Bakhvalov in a comment provided solution for his own question. The solution is to move getCount function from header to source file and export/import it.
This seems to be the only solution portable between GCC and MSVC. Or to be more precise MSVC allows more solutions to this problem but none of them will work when program is build under GCC.
The variable trick
The above is not entirely true. There is another workaround that will work consistently between GCC and MSVC.
This is to stop using static local variable. Instead make it a global variable (most likely by making it static variable in the class) and export it. This will make the trick as well.
Sadly there is no way (or I don't know any) to directly force exporting/importing static local variables. You have to change them to global variables to do that.
MSVC solutions
With MSVC you have more options.
As mentioned before exporting/importing the inlined function itself (whether directly or through type) will do the job.
Summary
As described above even consistency between GCC and MSVC on Windows only requires care. You have to limit yourself to stay in common subset of allowed solutions.
Keeping the program (source) interoperable between Linux and Windows even if with same compiler (GCC) also requires care.
Luckily there is a common subset for all three environments: GCC on Linux, GCC on Windows and MSVC on Windows. That common subset is described already by mentioned Denis' comment.
So do not inline functions that you intend to export/import. Keep them in sources. And on Windows builds (regardless of compiler) export them explicitly (otherwise you will get linker error anyway since the functions in sources of a shared library will not be available when building program).
Note that this is actually a reasonable approach on its own. Inlining function from shared library doesn't seem wise. It freezes not only the interface but also implementation (of that function). You can no longer change this function freely (and deliver new version of your shared library) since all clients would have to be rebuild since they could have inlined that function. So it is a wise approach by itself not to inline from shared library. And as a bonus it assures that your sources are multi-platform friendly.
Also do have a look into the mentioned Visibility entry on GCC Wiki. It might be reasonable to use that approach (of explicit exports) on Linux as well since it seems cleaner (from design point of view) and more efficient at runtime. While it fits well what you have to do for Windows anyway.

C++ mangling name for use in Emscripten

I'm trying to compile a simple HelloWorld Prgramm from C++ to Javascript using emscripten.
It works fine when I include a main function which call's e.g. the multi function.
Here is my code (HelloWorld.cpp).
#include <stdio.h>
class HelloWorld {
public: void sayHello() {
printf("Hello World Klasse! %f", multi(7));
}
public: double multi(double x){
return x * x;
}
};
However if I don't include a main function the emcc compile always put's out
ERROR root: No functions to process. Make sure you prevented LLVM
from eliminating them as dead (use EXPORTED_FUNCTIONS if necessary,
see the FAQ)
I know about the 'EXPORTED_FUNCTIONS' option which tells what functions should be included into the compile .js file.
I tried various diffrent things:
Using the mangling name, as far as I understood this the name should be '_multi_d10HelloWorldd'. I also tried without classname and some other combinations.
emcc -s HelloWorld.cpp -s EXPORTED_FUNCTIONS='["_multi_d10HelloWorldd"]'
Using the modifier EXPORT_ALL
emcc -s HelloWorld.cpp -s EXPORT_ALL=1
Whatever I do the functions won't be included in the final js file.
From what I understand from the EMCC FAQ I need to use EXPORTED_FUNCTIONS so I can later on call the desired function e.g. 'sayHello' from JS unsing the same method name.
And this is exactly what I need to do later on.
Could someone please point me to a solution or any other possible option which I may have not thought of ?
Is the mangling name I thought of correct ?
Create an "extern c" block. Inside this block define the functions you want to expose to javascript. These functions should be prefixed with an underscore. Inside one of these functions you can instantiate your C++ class.
This is the same approach as one would take when writing a dynamic library, which has the advantage that you can reuse your library in a native program should you wish.

error occured when fortran code called c code

I have used a method in a reference book about fortran codes calling c codes. The method is that if your function name in the c codes are capitalized, you may not make additional changes in your fortran code. The following is my code.
Source1.f90:
program main
implicit none
call c_subprint()
endprogram
ccode.c:
#include <stdio.h>
#include <string.h>
#ifdef _cplusplus
extern "C" {
#endif
void _stdcall C_SUBPRINT()
{
int a;
printf("%s\n","kk");
scanf("%d",&a);
}
#ifdef _cplusplus
}
#endif
The error message is that the main function cannot find out _C_SUBPRINT(LNK2019). But I have already added the .lib generated by the c code to the fortran code. And my code is almost the same as that in the reference book. what is wrong?
Different Fortran compilers generate calls differently. Many add underscores to routine names to avoid name conflicts with C-code. Its very hard to say whether or not you should exactly follow the example of an unnamed reference book. In the past, to mix Fortran and C, you have to understand some of the compiler internals. Here the Fortran compiler appears to have added an underscore to the start of the name. You could probably fix the problem by adding that in your C++ code. But that won't be portable and in principle could change with compiler versions. There is a better way: the Fortran ISO_C_Binding. This is part of the Fortran language standard and therefore standard and portable. Examples are given in the gfortran manual in the Chapter "Mixed-Language Programming" and in other questions on Stackoverflow.
From the inclusion of _stdcall I deduce you are probably using a Windows platform. Unfortunately I'm working on a Mac, so things may not be exactly the same. However, the following works for me (small changes from your code) to get a mix of Fortran and C code working together. Note - on my Mac, the gcc compiler does not include Fortran, so I used a separate Fortran compiler gfortran which I downloaded from a link at http://hpc.sourceforge.net - where instructions for installation could also be found.
program src1.f90:
program main
implicit none
call C_SUBPRINT()
endprogram
program ccode.c:
#include <stdio.h>
#include <string.h>
void c_subprint_()
{
printf("hello world!\n");
}
Note I took out the #ifdef sections - I was using pure C, so it was not needed; more importantly, note the underscore after the function name
I compiled these two modules as follows:
gcc -c ccode.c -o ccode.o
gfortran src1.f90 ccode.o -o hello
After which I can run
./hello
And get the expected output:
hello world!
Without the underscore, the linker complains about unknown symbols. There is an option in the compiler to turn off "name mangling" with the underscore. You can check your specific compiler to see how that would be done - but that's almost certainly the problem you are having.

resolving non-unique symbols between c++ wrapper libraries for fortran subroutines

I am working with two sets of FORTRAN code, for example, codeA.f and codeB.f. In each set of code there are subroutines with the same name, but which perform significantly different tasks (as well as common blocks).
codeA.f:
subroutine init
c do something here ...
end
codeB.f:
subroutine init
c do something else here ...
end
I create two C++ wrappers for both routines (wrapperB is identical, but swap B for A).
wrapperA.cpp:
namespace codeA {
extern "C"{void init_();}
void init() {init_();}
}
wrapperA.h:
namespace codeA {
init();
}
I then compile the two wrappers into shared libraries.
Makefile:
codeA.o : codeA.F
g77 -fno-automatic -fPIC -O3 -c codeA.f -o codeA.o
wrapperA.o : wrapperA.cpp
g++ -fPIC -c wrapperA.cpp -o wrapperA.o
libwrapperA.so : codeA.o wrapperA.o
g++ -fPIC -shared -lg2c codeA.o wrapperA.o -o libwrapperA.so
Finally, I want to be able to call the two different subroutines from the same program.
main.cpp:
#include "wrapperA.h"
#include "wrapperB.h"
main {
wrapperA::init();
wrapperB::init();
}
The main program is linked against the two shared wrapper libraries.
Makefile:
main : main.cpp
g++ main.cpp -I. -L. -lwrapperA -lwrapperB -o main
Everything compiles and there are no complaints. However, when the program "main" is run, the init() commands perform the same action, dictated by which of the wrapper libraries was linked against first. However, if I link against only one of the libraries, the linker complains about missing symbols.
I have two question about this:
a) Is it possible to link against two different FORTRAN routines using only namespaces or some similar method to what I am doing? If so, what am I doing wrong?
b) If a) is not possible, is it possible to resolve the conflicts by instructing the compiler to append the symbols with some unique identifier when creating the FORTRAN objects (I am using gcc version 4.1.2 20080704 (Red Hat 4.1.2-51))?
Thanks for any insight into this.
Your compile commands show the use of g77, which is no longer maintained and also implies the use of a very old version of Fortran (i.e., FORTRAN 77). You are also using an old version of gcc. If you use gcc and gfortran of version 4.3 or higher -- preferably 4.4 or higher -- then you can use the Fortran 2003 ISO C Binding to solve your problem. In the Fortran code you can assign externally visible names to the routines with the "bind" option of the ISO C Binding. Just assign different "bind" names to the two routines. Then they won't clash at the library & linker level:
In one Fortran file use
subroutine init (stuff...) bind (C, name="init_V1")
and the other file
subroutine init (stuff...) bind (C, name="init_V2")
and the routines will be visible to C, C++, the linker, etc. as init_V1 and init_V2 without clashing.
Have a look at this SO question, which is very similar to your problem : Static and shared library symbol conflicts?
Basically, you have two shared libraries defining different symbols : wrapperA::init() and wrapperB::init() ; but also conflicting symbols : _init__(). So when the linker resolves, it use the first of the conflicting symbol it find.
If you remove the unneeded external visibility of _init__() in your libraries by using the techniques given in the SO question : http://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html, then I think you will have solved your problem. Each wrapper::init() will then call internally it's proper _init__() without any conflict.

How do I get missing prototype warnings from g++?

I currently have a project that uses g++ to compile it's code. I'm in the process of cleaning up the code, and I'd like to ensure that all functions have prototypes, to ensure things like const char * are correctly handled. Unfortunately, g++ complains when I try to specify -Wmissing-prototypes:
g++ -Wmissing-prototypes -Wall -Werror -c foo.cpp
cc1plus: warning: command line option "-Wmissing-prototypes" is valid for Ada/C/ObjC but not for C++
Can someone tell me:
1) Why does gcc this isn't valid? Is this a bug in gcc?
2) Is there a way to turn on this warning?
EDIT:
Here's a cut and paste example:
cat > foo.cpp <<EOF
void myfunc(int arg1, int arg2)
{
/* do stuff with arg1, arg2 */
}
EOF
g++ -Wmissing-prototypes -c foo.cpp # complains about not valid
g++ -c foo.cpp # no warnings
# Compile in C mode, warning appears as expected:
g++ -x c -Wmissing-prototypes -c foo.cpp
When you compile a file with .cpp extension, it is compiled as C++ code by default. In C++ language the requirement for function declarations is a mandatory, hard requirement. There's no point in making an -Wmissing-prototypes option for C++.
In other words, you can't "turn on this warning" in C++ because "missing prototype" is always an error in C++.
P.S. As a side note: The notion of prototype is specific to C language only. There are no "prototypes" in C++.
In C language a function declaration can be a prototype or not a prototype, hence the need for an extra term to distinguish ones from the others. In C++ function declarations are always "prototypes" (from C point of view), so in C++ there simply no need for this extra term. In C++ function declarations are simply function declarations. That just says it all.
EDIT: After reading your comment I came to conclusion that you must have misunderstood the meaning and the purpose of the -Wmissing-prototypes option and corresponding warning. Note, this option will not check whether you have included prototypes of all your functions into some header file. There is no option to do that in GCC, regardless of whether you are using C or C++.
The purpose of -Wmissing-prototypes is different. This option only works when you call a function that has no visible prototype at the point of the call. In C language doing this is legal, but if you'd like a warning in this case, you use -Wmissing-prototypes option. In C++ language calling a function that has no visible declaration ("prototype") at the point of the call is always an immediate error, which is why C++ compilers have no need for such option as -Wmissing-prototypes.
In other words, if you defined some function in some implementation file, but forgot to include a prototype for this function in some header file, you will not get any warnings from the compiler until you actually try to call that function. It doesn't matter whether your code is C or C++, whether you use -Wmissing-prototypes or not... Until you make an attempt to call the function, there will be no warnings.
But once you try to call a function without a prototype, the C compiler will report a warning (if you used -Wmissing-prototypes) and C++ compiler will always report an error.
-Wmissing-prototypes is not applicable for C++, because C++ always requires prototypes.
Take the following declaration for example:
void foo();
In C, foo can be called with any number and type of arguments.
In C++, foo does not take any arguments (compilation error if any arguments passed in).
Did you try -Wmissing-declarations? That seems to work for g++ and detect the error case you describe. I'm not sure which version they added it in, but it works for me in 4.3.3.