Detect compiler with #ifdef - c++

I'm trying to build a small code that works across multiple platforms and compilers. I use assertions, most of which can be turned off, but when compiling with PGI's pgicpp using -mp for OpenMP support, it automatically uses the --no_exceptions option: everywhere in my code with a "throw" statement generates a fatal compiler error. ("support for exception handling is disabled")
Is there a defined macro I can test to hide the throw statements on PGI? I usually work with gcc, which has GCC_VERSION and the like. I can't find any documentation describing these macros in PGI.

Take a look at the Pre-defined C/C++ Compiler Macros project on Sourceforge.
PGI's compiler has a __PGI macro.
Also, take a look at libnuwen's compiler.hh header for a decent way to 'normalize' compiler versioning macros.

You could try this to see what macros are predefined by the compiler:
pgcc -dM
Maybe that will reveal a suitable macro you can use.

Have you looked at the boost headers? Supposing they support PGI, they will have found a way to detect it. You could use that. I would start to search somewhere in boost/config.

Related

Visual Studio Code intellisense, use g++ predefined macros

I'm using Visual Studio Code for c++ with MinGW and g++. My code uses a couple of g++ predefined macros. These work in the compiler without any problem, but Intellisense doesn't know about the macros and that causes some misdiagnosed errors (and other Intellisense problems) in the editor.
I can get all the predefined macros for my particular configuration of g++ with this command:
g++ -dM -E foo.cpp > defines.h
And this allows me insert them into the "defines" property of the c_cpp_properties.json file. This solution is a hack though, and if I'm not careful it could completely undermine the purpose of these macros. I want the compiler and Intellisense to cooperate across multiple development platforms, and that's looking like a pretty complicated setup.
Is there a better way to let Intellisense know about the g++ predefined macros?
From what I can tell, Intellisense's ability to properly handle preprocessor macros is still limited. If you are using CMake for Makefiles, it appears that you can tell Intellisense what macros you have, as seen here: auto-defined macros. I have not played with this personally, but it would be worth investigating.
If you can't get this to work, I found a feature to just turn off the macro-based highlighting. In settings, set"C_Cpp.dimInactiveRegions" to false. This isn't ideal, because it stops all graying out, including debug blocks like if(0) {...}, but it could be a temporary fix and you might find it less irritating.
Apart from that, look closely for added features in future updates. I'll try to update this post when I find any new discoveries on the matter.
The property in c_cpp_properties.json called compilerPath allows IntelliSense to query the compiler for default include paths and defines. It may be necessary to set intelliSenseMode to gcc-x64 for this to work, as that is not the default on Windows. (I currently do not have a Windows setup so I can't test this for the time being)

Use clang-tidy on CUDA source files

Several static analysis tools designed for C/C++ exist, but they are not particularly useful for testing CUDA sources.
Since clang version 6 is able to compile CUDA, I wanted to check what are my options with using clang-tidy, which does not seem to have option for switching architectures.
Is there a way to make it work? For example compile time switch for turning on CUDA parser, extension in form of custom check, or is it maybe planned feature?
One of the problem with the clang-based tools is that they are not parsing the files in exactly the same way as clang does.
The first problem is that unlike C/C++ compilation, CUDA compilation compiles the source multiple times. By default clang creates multiple compilation jobs when you give it a CUDA file and that trips many tools that expect only one compilation. In order to work that around you need to pass --cuda-host-only option to clang-tidy.
You may also need to pass --cuda-path=/path/to/your/CUDA/install/root so clang can find CUDA headers.
Another problem you may run into would be related to include paths. Clang-derived tools do not have the same default include paths that clang itself uses and that occasionally causes weird problems. At the very least clang-tidy needs to find __clang_cuda_runtime_wrapper.h which is installed along with clang. If you run clang-tidy your-file.c -- -v it will print clang's arguments and include search paths it uses. Compare that to what clang -x c /dev/null -fsyntax-only -vprints. You may need to give clang-tidy extra include paths to match those used by clang itself. Note that you should not explicitly add the path to the CUDA includes here. It will be added in the right place automatically by --cuda-path=....
Once you have it all in place, clang-tidy should work on CUDA files.
Something like this:
clang-tidy your-file.cu -- --cuda-host-only --cuda-path=... -isystem /clang/includes -isystem /extra/system/includes

How to see macro expansions step-by-step?

It seems Eclipse allows user to "see the expansion Step-by-Step" by pressing F2.
I like this awesome feature. But can I do the same thing with just gcc or clang (or any tool)?
-E option makes all macros fully expanded. So I haven't found any alternative way to expand macros step-by-step.
Eclipse is big. I hope I don't need to install it everywhere and have it launched all the time.
It's a feature built into Eclipse. If such a tool was provided as part of the GCC or Clang toolchain, Eclipse would have no need to implement it. Such a feature could be implemented as an extension to GCC using MELT. LLVM (of which Clang is a part of) is designed to make something like this trivial.
One thing you have to keep in mind that macro expansion is a tricky business. At any given point in time, a macro definition may change or not exist at all. Theoretically you could use gdb (the debugger that comes with GCC) to step through your program to see macro expansions at different point in the program. If you want, you could try writing a gdb plugin in Python.

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 predefined macro can be used to detect debug build with clang?

MSVC defines _DEBUG in debug mode, gcc defines NDEBUG in release mode. What macro can I use in clang to detect whether the code is being compiled for release or debug?
If you look at the project settings of your IDE, you will see that those macros are actually manually defined there, they are not automatically defined by the compiler. In fact, there is no way for the compiler to actually know if it's building a "debug" or "release", it just builds depending on the flags provided to it by the user (or IDE).
You have to make your own macros and define them manually, just like the IDE does for you when creating the projects.
Compilers don't define those macros. Your IDE/Makefile/<insert build system here> does. This doesn't depend on the compiler, but on the environment/build helper program you use.
The convention is to define the DEBUG macro in debug mode and the NDEBUG macro in release mode.
You can use the __OPTIMIZE__ flag to determine if optimization is taking place. That generally means it is not a debug build since optimizations often rearrange the code sequence. Trying to step through optimized code can be confusing.
This probably is what those most interested in this question really are attempting to figure out.
There is no such thing as a debug mode in a command line compiler. That is a IDE thing: it just sets up some options to be sent to the compiler.
If you use clang from the command line, you can use whatever you want. The same is true for gcc, so if with gcc you use NDEBUG you can use just the same.