How to get GCC version supports specific feature? - c++

There are cases that I want to know since which version of gcc a specific compiler flag or c++ language feature is supported so that I can write compile control preprocessors in source files or in CMakeLists.txt. For example, the compiler flag -wno-missing-field-initializers is not supported in gcc 3.4.3(an ancient version I have to use), but I want to know exactly since which version does gcc support that flag. Where can I find such instructions?

You can check specific flags using CheckCXXCompilerFlag
For example,
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(-Wno-missing-field-initializers RESULT_OF_TEST)
Although a more portable option, across compilers, is to use CMAKE_CXX_KNOWN_FEATURES
See https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html

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.

Standard libraries of LLVM C++ and GNU C++ have different headers

I have to use unordered_map and trie, but not one standard library, nor another one contains both of them.
// works only with LLVM library
#include <unordered_map>
// works only with GNU library
#include <ext/pb_ds/assoc_container.hpp>
I mean which is described on the GCC GNU website.
The program is building in Xcode 7.2.1. I have tried to use GNU C++14, GNU C++11 and C++14, C++11, but it doesn't help.
How this problem may be solved? Probably, my GNU library is too old, can I update it in Xcode? Or, maybe, LLVM has assoc_container.hpp is some other path?
std::unordered_map came in with the C++11 standard, and not all compilers use C++11 (or later) as standard yet meaning you have to add flags when building to be able to use it.
When building with GCC versions prior to 5.1 you should add the flag -std=c++11 (or optionally -std=gnu++11 if you want GCC extensions, or -std=c++0x if you have a really old version of GCC).
An implementation of std::unordered_map is a requirement for C++11. This suggests you are using an older version of stdlibc++.
If you're stuck with that version, Boost provides an implementation that you could use.
You can't expect libc++ (Clang's C++ library) to have GNU extensions. You can, however, mix and match libstc++ and libc++ in the same executable (but not compilation unit) due to the latter's use of inline namespaces, which mean that its symbols won't clash with the former.
Edit:
Seems the OP is compiling on MacOSX using a recent version of clang.
In this case, the libstd++ shipping with the toolchain is a creaking old version without C++11 support. It is deprecated as far as Apple is concerned.
The best bet is to either: modify code to avoid use of extensions in libstdc++ - which in any case appear to C++11 pre-release features
or: build with both libraries (yes, this is totally possible on MacOSX and iOS). Caveat here is that you can only ever use one or the other in any compilation unit.

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.

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.

Clang vs. LLVMC -- what's the difference?

What's the difference between llvmc.exe and clang.exe? Which one do I use for compiling C or C++ code?
llvmc is a frontend for various programs in the LLVM toolchain, in particular the llvm-* ones, ie by default it will try to use llvm-gcc and llvm-g++ to compile C and C++ files.
You can pass -clang to llvmc if that's what you want to use, and it's probably possible to configure llvmc so clang will be used by default, but I have no idea how to do that.
I'd recommend to just use clang and clang++ directly, which can be used as drop-in replacements for gcc and g++.
llvmc was an experimental driver that was intended to support multiple different source languages. Clang and Clang++ have always been the preferred way to drive the (C / C++ / Objective-C) compiler. In fact, llvmc has been removed from mainline.
In short, you should definitely use "clang" and never "llvmc".
LLVM originally stands for Low-Level Virtual Machine, and is today mostly used either:
as a backend optimizer/compiler
as a JIT compiler
On the other hand, Clang is a collection of libraries for dealing with the C language family that notably contains a compiler (clang) which acts as a front-end for C, C++, Objective-C and Objective-C++ on top of the LLVM libraries.
So, in your case, you will want to use clang and clang++ to compile C and C++ respectively, and don't worry about the fact that LLVM is used behind the scenes to optimize your code and deal with generation of machine instructions adapted to your architecture.