How to compare disassembly of zero cost exceptions with the old approach? - c++

I want to understand how "zero-cost exceptions" differ from the previous approach used to compile exceptions, so I want to look at the assembly code of some program compiled using both, to compare them. How can I do that?
Is there a GCC option I can use to switch between them? Or is there an old version of GCC that uses the old approach (ideally one that's available on Godbolt's Compiler Explorer)? Or something else?
I'm interested in x64 on Linux.

According to this question, GCC on linux uses zero-cost exceptions by default but can be configured to use the old ones (SJLJ). It seems you will need to build GCC yourself (and configure with --enable-sjlj-exceptions)

Related

Are g++ and clang++ 100% binary compatible? [duplicate]

If I build a static library with llvm-gcc, then link it with a program compiled using mingw gcc, will the result work?
The same for other combinations of llvm-gcc, clang and normal gcc. I'm interested in how this works out on Linux (using normal non-mingw gcc, of course) and other platforms as well, but the emphasis is on Windows.
I'm also interested in all languages, but with a strong emphasis on C and C++ - obviously clang doesn't support Fortran etc, but I believe llvm-gcc does.
I assume they all use the ELF file format, but what about call conventions, virtual table layouts etc?
Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.
C++ is not portable between compilers in the slightest; different compilers use different virtual table calls, constructors, destruction, name mangling, template implementations, etc. As a rule you should assume objects from one C++ compiler will not work with another.
However yes, at the time of writing Clang++ is able to use GCC/C++ compiled libraries as well; I recently set up a rig to compile C++ programs with clang using G++'s standard runtime library and it compiles+links just fine.
I don't know the answer, but slide 10 in this presentation seems to imply that the ".o" files produced by llvmgcc contain LLVM bytecode (.bc) instead of the usual target-specific object code, so that link-time optimization is possible. However, the LLVM linker should be able to link LLVM code with code produced by "normal" GCC, as the next slide says "link in native .o files and libraries here".
LLVM is a Linux tool, I have sometimes found that Linux compilers don't work quite right on Windows. I would be curious whether you get it to work or not.
I use -m i386pep when linking clang's .o files by ld. llvm's devotion to integrating with gcc is seen openly at http://dragonegg.llvm.org/ so its very intuitive to guess llvm family will greatly be cross-compatible with gcc tool-chain.
Sorry - I was coming back to llvm after a break, and have never done much more than the tutorial. First time around, I kind of burned out after the struggle getting LLVM 2.6 to build on MinGW GCC - thankfully not a problem with LLVM 2.7.
Going through the tutorial again today I noticed in Chapter 5 of the tutorial not only a clear statement that LLVM uses the ABI (Application Binary Interface) of the platform, but also that the tutorial compiler depends on this to allow access to external functions such as sin and cos.
I still don't know whether the compatible ABI extends to C++, though. That's not an issue of call conventions so much as name mangling, struct layout and vtable layout.
Being able to make C function calls is enough for most things, there's still a few issues where I care about C++.
Hopefully they fixed it but I avoid llvm-gcc because I (also) use llvm as a cross compiler and when you use llvm-gcc -m32 on a 64 bit machine the -m32 is ignored and you get 64 bit ints which have to be faked on your 32 bit target machine. Clang does not have that bug nor does gcc. Also the more I use clang the more I like. As to your direct question, dont know, in theory these days targets have well known or used calling conventions. And you would hope both gcc and llvm conform to the same but you never know. the simplest way to find this out is to write a couple of simple functions, compile and disassemble using both tool sets and see how they pass operands to the functions.

SSE4.1 automatically put in string comparison on newer gcc

I searched the gcc 4.8.1 documents but couldn't find an answer to this:
I have some SSE4.1 code and fallback code, at runtime I detect whether the system supports SSE4.1 and in case it doesn't, I use the fallback code.
So far so good, but with latest gcc versions this is what happens:
- my application crashes because SSE4.1 instructions are being spread throughout the code every time a string comparison is performed
Since I'm compiling all my files with -msse41 this sounds reasonable but crashes my code. My question is this: is there any way to restrict SSE41 usage to just that code which makes use of SSE4.1? Unfortunately these are header files used everywhere so it would be rather difficult to just compile those translation units with msse41
As of GCC 4.8, you can use multi-versioned functions, see http://gcc.gnu.org/gcc-4.8/changes.html, look for "Function Multiversioning Support with G++". Disclaimer: I did not use this (as of yet).

Disable std::map::at()

I'm compiling some code with gcc4.7, which was written for c++11, but I'd like it to be compatible with gcc4.4. The weird thing is that code with std::map::at() (which is only supposed to be defined in c++11) used doesn't seem to give me compiling errors, even after I remove the -std=c++11 flag. I'd like to be getting compiler errors, since this code has to be shared with colleagues who may not be using gcc4.7. Is this normal? Is there some way to restrict the behavior of std::map?
Apparently it is not possible to achieve this with a new gcc and new libraries, at least without compiling them yourself.
As a practical solution, assuming you have a relatively modern PC (6+GB of memory, perhaps 4GB will do), I suggest you
Install an older Linux distro in a virtual machine, which has both the desired old gcc, and matching old standard libraries. This is far less hassle, than trying to set up an alternative compiler and library environment in your main development OS.
Keep your sources in version control, if you already don't.
Either set up a script in the old VM to check out and build the software manually, or go the extra mile, and set up a Jenkins on the VM, and create a job to poll your version control repo and do a test build automatically when you do commit on your main development environment.
Good thing about this is, you can easily set up as many different environments and OSes as you want to keep compatibility with, and still keep the main development OS up to date with latest versions.
Original answer for the ideal world where things work right:
To get strict C++03, use these flags:
-std=c++03 -pedantic
Also, if you only want to support gcc, you may want -std=g++03 "standard" instead, but unless there is some specific feature, say C99-style VLA, which you really want to use, then I'd recommend against that. You never know what compiler you or someone else may want to use in the future.
As a side note, also recommended (at least if you want to fix the warnings too): -Wall -Wextra
Sad reality looks like selecting the C++ standard indeed does not solve the problem. As far as I can tell, this is not really a problem in the gcc compiler, it is a problem in the GNU C++ standard library, which evidently does not check the desired C++ standard version (with #ifdefs in header files). If it bothers you, you might consider filing a bug report (if there already isn't one, though I did not find one with a quick search).

Is it it possible to fix Windows headers (winnt.h, windefs.h) so they can be compiled with /Za?

I'm developing an application for multiple platforms (Windows, Linux, Mac OS X) and I want to make sure my code complies to ISO C++ standard. On Linux and Mac it's achieved with -pedantic-errors flag, on Windows - with /Za flag (disable language extensions). The problem is, some Windows headers are not C++-compliant (and in a silly way, nothing major - most errors are '$' : unexpected in macro definition, '__forceinline' not permitted on data declarations and similar nonsense). Do you think it would be possible to fix the headers? Has anyone tried that?
No, this is impossible. For a lovely discussion on the matter started by STL (the guy, not the acronym) on the Clang developers mailing list see here.
That being said, if you want to write standard conforming code, I suggest using MinGW-w64 GCC on Windows, which provides its own Win32 API headers that can be compiled with -std=c++11 -pedantic -Wall -Wextra. I can even offer you Clang 3.2. It's 32-bit only and relies on GCC 4.6's libstdc++, but they get along quite well. I have a Clang 3.3 build on my computer at home but libstdc++ and Clang disagree on some variadic template linking issues, so I haven't uploaded it.
Since you want to write a portable code - do it. Your windows headers have nothing to do with it. After you port your code to Linux for example you'll not have them so do not bother.
It is your code (that one that you write) that must be portable so do not worry about __forceinline within some header that will not even be on any different platform that you may use.
So - do not bother about warnings that are not from your code.
Update:
If these generate warnings you may supress them. If errors you may try the following:
as for _forceinlilne this is (at least in different compilers) just a suggestion for the compiler to try as hard to inline sth - but cannot force it - you may delete it safely if you really need to
as for other errors - please give an example
One possible solution is to use a mingw/cygwin gcc with the winapi headers that ship with them. They are not complete, so you might need to copy some declarations from the Windows SDK if you are using newer stuff. But, as others mentioned, your code is already not portable if you are using the windows headers.

How to properly switch between gcc versions?

I want to play with C++ 2011, so I need the unreleased gcc 4.7. I was able to succesfully get the svn trunk and compile it.
I want to keep the default gcc of my system for safety, so I configured gcc4.7 with a --prefix and installed it in a non-standard location.
Now how should I enable gcc 4.7 over the default gcc of my system ?
I already changed the CC and CXX variables, I updated my PATH to point on the gcc 4.7 bin dir first. When I type gcc --version I get 4.7 OK.
But gcc is more than just an executable. There are many executables in gcc install dir. There are also default includes and std lib c++.
So far, every blog entry / SO question I found on this subject speaks only about the gcc and g++ executables.
Can anyone give me a list of the changes I need to do to the environment to fully use gcc 4.7 ?
update LD_LIBRARY_PATH ? How to give precedence to gcc 4.7 system includes ? Are there other things to consider ?
Thanks in advance.
I would think that THE g++ is pretty much tangled up with things using C++ as the C library is tangled up with the system! Any layout changes in the C++ library classes will cause incompatibilities with other C++ programs or libraries. Thus, I wouldn't replace the system's C++ compiler or, more importantly, its standard C++ library at all (unless, maybe, the compiler vendor makes a strong claim that they retained binary compatibility with the version you are replacing).
To play or even use a different version of g++, using the prefix approach works fine. All the compiler specific tools are implicitly called from within g++ using an appropriate version and tools like ar, ld, ranblib, etc. are not really depending on the compiler version anyway. The important components uses internally are the standard library (both the headers and the library) and the preprocessor. When calling a version of g++ it figures out which of these it really needs.
BTW, when you want to play with C++2011 you can also have a look at clang.
The simplest answer is: nothing; it just works. :)
GCC finds what it needs first relative to itself, second in the "prefix" it was configured with, and finally in the standard places. By this means it's perfectly safe to relocate it wherever you like, as long as you relocate all of it - but beware that the fall back behaviour can hide brokenness if the install is incomplete.
Look at the GCC Configuration docs. I am using program suffixes to distinguish between the different GCC versions. To do that add, e.g., --progam-suffix=-4.7 to your ./configure invocation.