Is there a set of standard compiler options? - c++

I am making a project using qmake and I want it to be easy to compile by many users. So far I was developing only for Linux and only for the gcc compiler. I would like my project to be compilable on other platforms too.
So far I passed the compiler options (which I found in the gcc documentation) to qmake like this:
QMAKE_CXXFLAGS += -std=c++14 \
-ffloat-store \
-O3 \
But then I realized that these options may not be valid on other compilers and tried to find equivalent options for other popular compilers, such as clang or Intel. To my surprise I found out that:
The optimization options -O0, -O1, -O2, -O3 are common to all three compilers.
The -std=c++11 and -std=c++14 options are common to gcc and clang
As far as I know, -ffloat-store and some other options are present only in gcc.
I wonder, is there some set of options, that is either formally or informally standard?

POSIX defines something about the c99 command (but AFAIK nothing about C++).
However, the qmake utility will usually be able to find out (or at least to expect) what is the C++ compiler and how to invoke it. Notice that it is generating a Makefile
Outside of Qt you might consider cmake or autoconf. They both generate Makefile-s.
See also this answer (on Programmers).

No.
The C++ standard doesn't cover any compiler option. This is something that can vary wildly between different implementations (or even different versions of the same implementation).

Off the top of my head, there's almost nothing in common between the major compilers.
The truth is, any non-trivial project requires some fine-tuning both in-code and the build process when you're aiming for multiple platforms. Your best bet is in my experience (and this is largely opinion-based), to craft the build process for each compiler to be as simple as possible, and fix most of the 'quirks' via pragmas in a platform/compiler specific include file that you "auto-include" everywhere.

Related

Is it possible to use Clang-Tidy with QNX?

I have a QNX specific code and I want to use clang-tidy for static analysis. Is this possible?
I am struggling because clang-tidy is supported by the clang compiler, and QCC (QNX compiler) is based on GCC.
Potentially yes. clang-tidy works with C++ source files and it mostly doesn't matter what compiler you use. As long as your program would compile with Clang, you can use clang-tidy.
However, although Clang is mostly compatible with GCC, the compatibility is not 100% proof and it may be confused if you use GCC / QCC specific features that are foreign to Clang. With standard, non-experimental C++ there should not be a problem.
Another consideration is that clang-tidy is typically used in conjunction with "compilation database", which invokes it with exact compiler options that you use to compile the program. Here again, Clang supports most GCC options either fully, or ignores them for compatibility, but some new, obscure or QCC specific options do cause an error.

Does using -std=c++11 break binary compatibility?

I've looked hard for this question - it seems an obvious one to ask - but I haven't found it: Is a module compiled with "-std=c++11" (g++) binary compatible with modules that are not compiled with the option? (That is, can I link them together safely?) Both compilations would use the exact same version of g++.
To be more precise, using gcc 4.9.0, can I only use the "-std=c++11" on specific compilation units and then let the others compile without the option.
An authoritative reference can be found in gcc's C++11 ABI Compatibility page.
The short summary is: the are no language reasons the ABI gets broken but there are a number of mandated changes which cause the standard C++ library shipping with gcc to change.

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.

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.

What are the differences between -std=c++11 and -std=gnu++11?

What are the differences between -std=c++11 and -std=gnu++11 as compilation parameter for gcc and clang? Same question with c99 and gnu99? I know about C++ and C standards, it's the differences in the parameters that interest me.
I've read somewhere that it has to do with some extensions but it is not clear to me which ones and how to choose between one or the other for a new project.
As you have found out yourself, the difference between the two options is whether GNU extensions that violates/extend the C++ standard are enabled or not. The GNU C++ extensions are described here. You can also use most of the GNU C extensions (described here) in your C++ programs. It would be also useful to read about the -Wpedantic GCC option here.
Note that some extensions can still be in effect when using -std=c++11, as long as they do not contradict the standard. For instance, when using the MinGW compiler, I need the extensions for a working Boost.Lexical_Cast. But, as long as you don't use any of them, you are better off sticking to the standard without extensions for maximum portability. This might come in handy if you find yourself forced to change compiler.