I have a Ruby C file (a ruby gem) that prints system information. When I run rake install, it compiles the C code. My C code has pragmas like:
#if defined(__GNUC__) && !defined(__llvm__)
#pragma GCC optimize ("O3")
#pragma GCC diagnostic warning "-Wall"
#elif defined(__clang__)
#pragma clang optimize on
#pragma clang diagnostic warning "-Wall"
#endif
I would like to have a pragma that will work as an alternative to strip --strip-unneeded ~/.gem/ruby/2.7.0/gems/linux_stat-0.8.0/ext/fs_stat/fs_stat.so, because the user of this gem is say heroku, or maybe a container and I want the pragma to do that.
Related
From Clang's documentation:
When Clang compiles C++ code for Windows, it attempts to be compatible with MSVC.
In particular, Clang defines _MSC_VER.
MSVC does not support #pragma STDC FENV_ACCESS ON:
cl t125.c /std:c11
t125.c(11): warning C4068: unknown pragma 'STDC'
Instead MSVC does support #pragma fenv_access (on). This leads to this code:
#if _MSC_VER
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
Now try to compile this code using the latest Clang on Windows:
$ /cygdrive/d/SOFTWARE/LLVM/12.0.0/bin/clang t125.c -Wall -Wextra
t125.c:10:9: warning: unknown pragma ignored [-Wunknown-pragmas]
#pragma fenv_access (on)
Meaning that since #pragma fenv_access (on) is unknown pragma which is ignored, then the MSVC compatibility is underdone / unfinished? Confused.
Question: how to disable the default MSVC compatibility (so that Clang does not define _MSC_VER)?
P.S. This finally leads to this code:
#if _MSC_VER && ! __clang__ && ! __INTEL_COMPILER
#pragma fenv_access (on) /* true MSVC here?? */
#else
#pragma STDC FENV_ACCESS ON
#endif
UPD. Patch for supporting the MS spelling of the pragma: https://reviews.llvm.org/D111440.
how to disable the default MSVC compatibility (so that Clang does not define _MSC_VER)?
Adding either -fms-compatibility-version=0 or -fmsc-version=0 switch should prevent _MSC_VER from being defined. This and a few other related VC++ compatibility options are documented on the Clang command line argument reference page under Target-independent compilation options.
-fms-compatibility, -fno-ms-compatibility
Enable full Microsoft Visual C++ compatibility
-fms-compatibility-version=<arg>
Dot-separated value representing the Microsoft compiler version number to report in _MSC_VER (0 = don’t define it (default))
-fms-extensions, -fno-ms-extensions
Accept some non-standard constructs supported by the Microsoft compiler
-fms-memptr-rep=<arg>
-fms-volatile
-fmsc-version=<arg>
Microsoft compiler version number to report in _MSC_VER (0 = don’t define it (default))
I want to use #pragma clang diagnostic push to ignore warnings from some included header files. So I write this:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
#include "SpinGenApi/SpinnakerGenApi.h"
#include "Spinnaker.h"
#pragma clang diagnostic pop
But still the compiler prints warnings when compiling the file with this code. What do I need to change so that all warnings are ignored for these headers?
The answer seems to be in this case that -Wall contrary to its name did not include the warnings which I wanted to suppress. I added #pragma clang diagnostic ignored "-Weverything" as well and they went away.
I cannot make the method to temporarily disable warnings in GCC (see How to disable GCC warnings for a few lines of code) work, at least not for the "unknown-pragmas" warning.
Compiling this code ...
#pragma comment(user,"This should depend on the command line options")
#pragma GCC diagnostic warning "-Wunknown-pragmas"
#pragma comment(user,"This should cause a warning")
#pragma GCC diagnostic error "-Wunknown-pragmas"
#pragma comment(user,"This should cause an error")
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma comment(user,"This should be ignored")
... produces either no warning/error (except that the linker complais about a missing main), or when using -Wall or just -Wunknown-pragmas it produces one warning for each of the comment pragmas.
The behaviour that I would have expected is that each comment should have caused exactly what the comment says.
I think I can back my expectation with the documentation:
At the moment only warnings (normally controlled by ‘-W...’) can be controlled, and not all of them. Use -fdiagnostics-show-option to determine which diagnostics are controllable and which option controls them.
The warnings I get show as
warning: ignoring #pragma comment [-Wunknown-pragmas]
and as the part in brackets tells us,
this diagnostic is controllable
and the option -Wunknown-pragmas controls it
Hence my code should work.
So what am I doing wrong?
version info:
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
This is a long-standing missing feature in the GCC C++ front end:
C++ preprocessor ignores #pragma GCC diagnostic
Warnings generated by preprocessing cannot be controlled using programs in g++. Unlike the C front end, pragmas are processed only after the preprocessing phase in the C++ front end.
I would like to disable specific known warnings in C++ code coming from a library header when compiling my own code. There are clang and gcc specific methods for disabling the warnings. The way this is done is almost identical.
For clang:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#include <library.h>
#pragma clang diagnostic pop
For gcc:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <library.h>
#pragma GCC diagnostic pop
Is there a clean way to suppress these warnings that is portable across clang and GCC?
Which of these should I use to ignore a warning?
#pragma clang diagnostic ignored "-W<warning>"
#pragma GCC diagnostic ignored "-W<warning>"
Both seems to work for me, however which one is the correct to use?
Should I always use the one matching the compiler I'm using?
Generally, you should prefer #pragma GCC in cases where the pragma is GCC-specific, or is equally applicable to GCC, Clang, and other compilers which try to be GCC-compatible (such as ICC). Use #pragma clang in cases where the pragma is in some way Clang-specific (such as a diagnostic option which doesn't exist in GCC).