I am just trying my hands on g++ 4.6 and C++11 features.
Every time I compile a simple threading code using -std=c++0x flag, either it crashes with segmentation fault or it just throws some weird exception.
I read some questions related to C++11 threads and I realized that, I also need to use -pthread flag to compile the code properly. Using -pthread worked fine and I was able to run the threaded code.
My question is, whether the C++11 multi-threading model uses Pthreads in the background?
Or is it written from the scratch?
I don't know if any of the members are gcc contributors but I am just curious.
If you run g++ -v it will give you a bunch of information about how it was configured. One of those things will generally be a line that looks like
Thread model: posix
which means that it was configured to use pthreads for its threading library (std::thread in libstdc++), and which means you also need to use any flags that might be required for pthreads on your system (-pthread on Linux).
This has nothing specific to do with the standard, its just a detail of how the standard is implemented by g++
C++ doesn't specify how threads are implemented. In practice C++ threads are generally implemented as thin wrappers over pre-existing system thread libraries (like pthreads or windows threads). There is even a provision to access the underlying thread object with std::thread::native_handle().
The reason that it crashes is that if you do not specify -pthreads or -lpthreads, a number of weakly defined pthreads stub functions from libc are linked. These stub functions are enough to get your program to link without error. However, actually creating a pthread requires the full on libpthread.a library, and when the dynamic linker (dl) tries to resolve those missing functions, you get a segmentation violation.
Related
Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.
I've been struggling a weird problem the last few days. We create some libraries using GCC 4.8 which link some of their dependencies statically - eg. log4cplus or boost. For these libraries we have created Python bindings using boost-python.
Every time such a library used TLS (like log4cplus does in it's static initialization or stdlibc++ does when throwing an exception - not only during initialization phase) the whole thing crashed in a segfault - and every time the address of the thread local variable has been 0.
I tried everything like recompiling, ensuring -fPIC is used, ensuring -tls-model=global-dynamic is used, etc. No success. Then today I found out that the reason for these crashes has been our way of linking OpenMP in. We did this using "-lgomp" instead of just using "-fopenmp". Since I changed this everything works fine - no crashes, no nothing. Fine!
But I'd really like to know what the cause of the problem was. So what's the difference between these two possibilities to link in OpenMP?
We have a CentOS 5 machine here where we have installed a GCC-4.8 in /opt/local/gcc48 and we are also sure that the libgomp coming from /opt/local/gcc48 had been used as well as the libstdc++ from there (DL_DEBUG used).
Any ideas? Haven't found anything on Google - or I used the wrong keywords :)
OpenMP is an intermediary between your code and its execution. Each #pragma omp statement are converted to calls to their according OpenMP library function, and it's all there is to it. The multithreaded execution (launching threads, joining and synchronizing them, etc.) is always handled by the Operating System (OS). All OpenMP does is handling these low-level OS-dependent threading calls for us portably in a short and sweet interface.
The -fopenmp flag is a high-level one that does more than include GCC's OpenMP implementation (gomp). This gomp library will require more libraries to access the threading functionality of the OS. On POSIX-compliant OSes, OpenMP is usually based on pthread, which needs to be linked. It may also need the realtime extension library (librt) to work on some OSes, while not on some other. When using dynamic linking, everything should be discovered automatically, but when you specified -static, I think you've fallen in the situation described by Jakub Jelinek here. But nowadays, pthread (and rt if needed) should be automatically linked when -static is used.
Aside from linking dependencies, the -fopenmp flag also activates some pragma statement processing. You can see throughout the GCC code (as here and here) that without the -fopenmp flag (which isn't trigged by only linking the gomp library), multiple pragmas won't be converted to the appropriate OpenMP function call. I just tried with some example code, and both -lgomp and -fopenmp produce a working executable that links against the same libraries. The only difference in my simple example that the -fopenmp has a symbol that the -lgomp doesn't have: GOMP_parallel##GOMP_4.0+ (code here) which is the function that initializes the parallel section performing the forks requested by the #pragma omp parallel in my example code. Thus, the -lgomp version did not translate the pragma to a call to GCC's OpenMP implementation. Both produced a working executable, but only the -fopenmp flag produced a parallel executable in this case.
To wrap up, -fopenmp is needed for GCC to process all the OpenMP pragmas. Without it, your parallel sections won't fork any thread, which could wreak havoc depending on the assumptions on which your inner code was done.
After installing gcc and mpich library in my linux I can compile my codes with mpicxx compiler. Is it possible to use c++11 with mpi library with just upgrading gcc compiler?
Changing the compiler with a newer version should work in general unless some strong code generation changes are observed (e.g. different data alignment or different ABIs). MPI is a library and as such it doesn't care what language constructs you are using as long as those constructs don't mess up with its internals. Since you are going to use C++11 for the threading it provides, there are some things that you should be aware of.
First, multithreading doesn't always play nice with MPI. Most MPI implementations are internally threaded themselves but are not thread safe by default.
Second, MPI defines four levels of threading support:
MPI_THREAD_SINGLE: no threading support - MPI would function safely only when used by a single-threaded application;
MPI_THREAD_FUNNELED: partial threading support - MPI can be used in a multithreaded application but only the main thread may call to MPI;
MPI_THREAD_SERIALIZED: partial threading support - MPI can be used in a multithreaded application but no concurrent calls in different threads are allowed. That is, each thread can call into MPI but a serialisation mechanism has to be in place;
MPI_THREAD_MULTIPLE: full threading support - MPI can be called freely from many threads.
Truth is most MPI implementations support out of the box MPI_THREAD_FUNNELED at max with most of them supporting only MPI_THERAD_SINGLE. Open MPI for example has to be compiled with a non-default option in order to get the full threading support.
Multithreaded applications should initialise the MPI library using MPI_Init_thread() instead of MPI_Init() and the thread that makes the initialisation call becomes the main thread - the very same main thread that is only allowed to call into MPI when the supported level is MPI_THREAD_FUNNELED. One gives MPI_Thread_init() the desired level of threading support and the function returns the supported level which might be lower than desired. In the latter case correct and portable programs are supposed to act accordingly and either switch to non-threaded operation or abort with the respective error message to the user.
More information about how MPI works together with threads can be found in the MPI Standard v2.2.
No problem as far as I can think of, since you shouldn't be able to tamper with the MPI directives in any way, and other than that, MPI and C++11 concerns are orthogonal.
By the way, issuing mpic++ or mpicxx on my machine (gcc 4.6.3, MPICH2 1.4.1) simply translates into
c++ -Wl,-Bsymbolic-functions -Wl,-z,relro -I/usr/include/mpich2 -L/usr/lib -lmpichcxx -lmpich -lopa -lmpl -lrt -lcr -lpthread
You can check that on your own machine with mpic++ -show.
It is no problem to combine C++11 with MPI.
mpic++ and mpicxx are only wrappers and use either the standard compiler or the user speciifed compiler. So you can define that mpic++ and mpicxx use a compiler with is compatible to C++11.
I do not know the exact command for mpich. For opemmpi you need to set these environment flags:
export OMPI_CC='gcc-mp-4.7'
export OMPI_CXX='g++-mp-4.7'
In my case I use openmpi 1.5.5 with the gcc 4.7 compiler from macports.
Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.
I am wondering if it is possible to link a c++ program compiled with gcc4.2 with a shared c++ library that is compiled in a later version like gcc4.5.
I've tried to do this, but have run into some different kind of problems.
When compiling the shared library gcc5.3 I get a message saying:
*"malloc: error for object 0x7fff707d2500: pointer being freed was not allocated
set a breakpoint in malloc_error_break to debug"*.
If I try to compile the shared library with gcc4.6 I get really strange behaviour. The std::stringstream class is not working correctly. The resulting string is empty after writing to the stream.
Is it possible to do this? Or am I trying something that is impossible? I was hoping that this was possible since I'm linking the lib dynamically. Btw I'm running on MacOSX.
BR
Beginning with gcc 3.0, g++ follows the Itanium ABI, so in theory there should be no problem. However, g++ 4.2 has CXXABI_1.3.1 whereas g++ 4.5 has CXXABI_1.3.4 (see here). Therefore I'd be careful. One does not bump up revision numbers if there are no differences.
Further, the glibc++ has gone through 5 revisions between those versions, which may be one reason why you see std::stringstream do funny things.
Lastly, there exist many config options (such as for example making strings fully dynamic or not) which affect the behaviour and compatibility of the standard library directly. Given two (random, unknown) builds, you cannot even know that they have the same config options.
In my experience the ABI compatibility means that C++ libraries can link to each-other without problems.
However, because C++ uses so many inline functions this doesn't mean much.
If the Standard C++ Library used all inline functions or used all library functions then you could use code compiled with older versions of GCC with newer versions.
But it doesn't. The library mixes inline and external library code. This means that if something is changed in std::string, or std::vector or locales or whatever, then the inlined code from the old GCC is out of sync with the library code linked from the new GCC.