How can I hide "defined but not used" warnings in GCC? - gcc

I have a bunch of compile time asserts, such as:
CASSERT(isTrue) or CASSERT2(isTrue, prefix_)
When compiling with GCC I get many warnings like 'prefix_LineNumber' defined but not used. Is there a way I can hide warnings for compile time asserts? I had no luck searching the GCC documentation. I thought I might have the var automatically used globally inside the same macro but I couldn't think of any way to do it.
Does anyone know of a way to hide that warning in GCC?

Just saw this thread while searching for solutions to this problem. I post here for completeness the solution I found...
The GCC compiler flags that control unused warnings include:
-Wunused-function
-Wunused-label
-Wunused-parameter
-Wunused-value
-Wunused-variable
-Wunused (=all of the above)
Each of these has a corresponding negative form with "no-" inserted after the W which turns off the warning (in case it was turned on by -Wall, for example). Thus, in your case you should use
-Wno-unused-function
Of course this works for the whole code, not just compile-time asserts. For function-specific behaviour, have a look at Function attributes.

Solution for GCC not causing conflicts with other compilers
#ifdef __GNUC__
#define VARIABLE_IS_NOT_USED __attribute__ ((unused))
#else
#define VARIABLE_IS_NOT_USED
#endif
int VARIABLE_IS_NOT_USED your_variable;

This is one of the most anoying warnings, although I undestand that it may useful (sometimes) to check dead code. But I usually have static functions for debugging, or functions that maybe useful sometime in the future, or that are only used temporaly, and I want to keep them in the code.
Fortunately this warning does not care about inline functions.
inline static foo()
{
}

You can create a null statement and cast the result to void. This is portable across compilers, and gcc will not give you any warnings, even with -Wall and -Wextra enabled. For example:
int var; // var is not used
(void)var; // null statement, cast to void -- suppresses warning
A common technique is to create a macro for this:
#define UNUSED(x) ((void)(x))
int var;
UNUSED(var);

#define UNUSED_VAR __attribute__ ((unused))
for any variable just use the above macro before its type for example:
UNUSED_VAR int a = 2;

Wrap this functions by the following directives
All the code that will be placed between push and pop will not warn you about unused functions.
All the rest of the code (outside push and pop) will not be affected.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
... your code
#pragma GCC diagnostic pop

This is hard to answer without knowing the details of your static assert macros. Perhaps you could change to a different macro to avoid this problem? You could either add the 'unused' attribute to the macro as was suggested, or you could use a different form of CASSERT().
Here are descriptions of a few alternatives:
http://www.jaggersoft.com/pubs/CVu11_3.html
http://blog.kowalczyk.info/kb/compile-time-asserts-in-c.html
http://www.pixelbeat.org/programming/gcc/static_assert.html

How about -Wunused-label ?

As of C++ 17 you can use [[maybe_unused]].
For example,
[[maybe_unused]] int foo = 42;
which has the same effect as the old(er) __attribute__((unused)).

Related

"string safe functions" and gcc

I'm using CodeBlocks and GCC compiler. I'd like to use "string safe functions" e.g strlen_s, strcpy_s, but compiler shows an error:
Undefined reference to strlen_s.
I then add a line to the code:
#define __STDC_WANT_LIB_EXT1__ 1
As well as writing the following in the Compiler Options (settings -> compiler -> global compiler settings -> other compiler options):
-std=c11
In the book that I'm reading there's a code to checking whether my compiler supports these functions. The code is as follows:
#include <stdio.h>
int main()
{
#if defined __STDC_WANT_LIB_EXT1__
printf("optional functions are defined");
#else
printf("optional functions are not defined");
#endif
return 0;
}
When I run this code I see "optional functions are defined". I've also reinstalled CodeBlocks but I still get these errors.
Should I install another compiler? If I should, which one will be the best?
#define __STDC_WANT_LIB_EXT1__ 1 is expected to be defined by your application - you have to define it yourself to enable the use of the bounds-checking interface functions.
In order to see if the bounds-checking interface is at all available, you need to check if __STDC_LIB_EXT1__ is defined by the compiler.
Note that no function called strlen_s exists.
This test is not sufficient, you should also test whether the implementation defines the macro __STDC_LIB_EXT1__.
These functions are from a part of the C standard that is called "Annex K" and that is optional. With this macro you test if your C library provides that feature, with the WANT macro defined before any includes you tell the compiler that you want to use these features from Annex K.
Annex K is much controversial, and not many public domain C libraries implement it. Many people think that its interfaces don't provide the security that it claims.
And for the book that you are reading this doesn't seem to be too reliable. But then, I may be biased on that point.

Why does gcc4.9 not display warning message -std=c++1y while using C++14 feature?

I installed gcc4.9 using the steps mentioned in the SO post here. I was using the latest feature std::exchange() utility function which is introduced in C++14.
#include<list>
#include<utility>
int main() {
std::list<int> lin{5,6,7,8,9};
auto lout = std::exchange(lin, {1,2,3,4});
return 0;
}
I performed following steps to compile the above sample program and got the following compilation error. After sometime I realized that (as there is no warning/hint by compiler message) this feature has been added in the C++14 standard so I need to use -std=c++1y here.
$g++ -std=c++11 main.cpp
main.cpp: In function ‘int main()’:
main.cpp:5:14: error: ‘exchange’ is not a member of ‘std’
auto lout = std::exchange(lin, {1,2,3,4});
^
If we use the C++11 standard feature and does not provide -std=c++11, then GCC gives warning message/hint that your program is using the feature which is introduced in the C++11 as below:
main.cpp:4:21: warning: extended initializer lists only available with
-std=c++11 or -std=gnu++11
std::list<int> lin{5,6,7,8,9};
This message is great and lets the user distinguish between the actual compilation error message and not including -std=c++11 option.
However while using gcc4.9 for C++1y feature under -std=c++11, there is no such warning message/hint? I wanted to know what could be the possible reason for this?.
The error/warning about "extended initializer lists" is emitted by the C++ parser. The C++
parser apparently knows how to parse that syntactic construct, understands it and can
provide a sensible error/warning message.
With the function, the situation is a little bit different. The GCC proper does not
contain knowledge about each and every standard function. For some functions it does, but
for most functions it doesn't.
From the compiler proper point of view, std::exchange is just an unknown identifier, the compiler does not contain special knowledge about the standard function std::exchange, and, hence, treats it as any other unknown identifier.

How to #define __forceinline inline?

I have some Microsoft code (XLCALL.CPP) which I am trying to compile with CodeBlocks/MinGW.
At this line I get a compile time error:
__forceinline void FetchExcel12EntryPt(void)
This is the error message I get:
XLCALL.CPP|36|error: expected constructor, destructor, or type
conversion before 'void'
This error is expected, because __forceinline is a Microsoft specific addition to the language, not recognized by GCC.
So, to get things compile, I try to add thiese defines in CodeBlocks (Project Build Options/Compiler Settings/#defines):
#define __forceinline inline
#define __forceinline
However I still get the same error.
If in the dialog I do not specify the #define preprocessor command (i.e.: __forceinline inline), this is what I get:
XLCALL.CPP|36|error: expected unqualified-id before numeric constant
Is there a way to compile such a piece of code, without using Visual C++?
The syntax is __forceinline=inline, as you've noted in the comments, because these settings get turned into -D options to GCC.
Note that inline is a strong hint to GCC that the function should be inlined, but does not guarantee it. The GCC equivalent of __forceinline is the always_inline attribute - e.g. this code:
#define __forceinline __attribute__((always_inline))
or equivalently this setting:
__forceinline="__attribute__((always_inline))"
(But this might well be unnecessary: if there was some particularly good reason for forcing this function to be inlined when compiling with MSVC, that reason may well not be valid when using a completely different compiler!)

Getting GCC to compile without inserting call to memcpy

I'm currently using GCC 4.5.3, compiled for PowerPC 440, and am compiling some code that doesn't require libc. I don't have any direct calls to memcpy(), but the compiler seems to be inserting one during the build.
There are linker options like -nostdlib, -nostartfiles, -nodefaultlibs but I'm unable to use them as I'm not doing the linking phase. I'm only compiling. With something like this:
$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c
If I check the output.o with nm, I see a reference to memcpy:
$ powerpc-440-eabi-nm output.o | grep memcpy
U memcpy
$
The GCC man page makes it clear how to remove calls to memcpy and other libc calls with the linker, but I don't want the compiler to insert them in the first place, as I'm using a completely different linker (not GNU's ld, and it doesn't know about libc).
Thanks for any help you can provide.
There is no need to -fno-builtins or -ffreestanding as they will unnecessarily disable many important optimizations
This is actually "optimized" by gcc's tree-loop-distribute-patterns, so to disable the unwanted behavior while keeping the useful builtin capabilities, you can just use:
-fno-tree-loop-distribute-patterns
Musl-libc uses this flag for its build and has the following note in their configure script (I looked through the source and didn't find any macros, so this should be enough)
# Check for options that may be needed to prevent the compiler from
# generating self-referential versions of memcpy,, memmove, memcmp,
# and memset. Really, we should add a check to determine if this
# option is sufficient, and if not, add a macro to cripple these
# functions with volatile...
# tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns
You can also add this as an attribute to individual functions in gcc using its optimize attribute, so that other functions can benefit from calling mem*()
__attribute__((optimize("no-tree-loop-distribute-patterns")))
size_t strlen(const char *s){ //without attribute, gcc compiles to jmp strlen
size_t i = -1ull;
do { ++i; } while (s[i]);
return i;
}
Alternatively, (at least for now) you may add a confounding null asm statement into your loop to thwart the pattern recognition.
size_t strlen(const char *s){
size_t i = -1ull;
do {
++i;
asm("");
} while (s[i]) ;
return i;
}
Gcc emits call to memcpy in some circumstance, for example if you are copying a structure.
There is no way to change GCC behaviour but you can try to avoid this by modifying your code to avoid such copy. Best bet is to look at the assembly to figure out why gcc emitted the memcpy and try to work around it. This is going to be annoying though, since you basically need to understand how gcc works.
Extract from http://gcc.gnu.org/onlinedocs/gcc/Standards.html:
Most of the compiler support routines used by GCC are present in libgcc, but there are a few exceptions. GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp. Finally, if __builtin_trap is used, and the target does not implement the trap pattern, then GCC will emit a call to abort.
You need to disable a that optimization with -fno-builtin. I had this problem once when trying to compile memcpy for a C library. It called itself. Oops!
You can also make your binary a "freestanding" one:
The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard [...]; a conforming freestanding implementation is only required to provide certain library facilities: those in , , , and ; since AMD1, also those in ; and in C99, also those in and . [...].
The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined, and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function int main (void) or int main (int, char *[]).
An OS kernel would be a freestanding environment; a program using the facilities of an operating system would normally be in a hosted implementation.
(paragraph added by me)
More here. And the corresponding gcc option/s (keywords -ffreestanding or -fno-builtin) can be found here.
This is quite an old question, but I've hit the same issue, and none of the solutions here worked.
So I defined this function:
static __attribute__((always_inline)) inline void* imemcpy (void *dest, const void *src, size_t len) {
char *d = dest;
const char *s = src;
while (len--)
*d++ = *s++;
return dest;
}
And then used it instead of memcpy. This has solved the inlining issue for me permanently. Not very useful if you are compiling some sort of library though.

Selectively remove a warning message using GCC

This piece of code:
Int32 status;
printf("status: %x", status)
gives me the following warning:
jpegthread.c:157: warning: format '%x' expects type 'unsigned int', but argument 3 has type 'Int32'
I know I can get rid of it by casting the type, but is it possible with a GCC compiler flag to get rid of that particular type of warning, and still use -Wall?
If you need that code to work portable then you should cast the argument to unsigned int, as the int type may have a different size than Int32 on some platforms.
To answer your question about disabling specific warnings in GCC, you can enable specific warnings in GCC with -Wxxxx and disable them with -Wno-xxxx.
From the GCC Warning Options:
You can request many specific warnings with options beginning -W, for example -Wimplicit to request warnings on implicit declarations. Each of these specific warning options also has a negative form beginning -Wno- to turn off warnings; for example, -Wno-implicit. This manual lists only one of the two forms, whichever is not the default.
For your case the warning in question is -Wformat
-Wformat
Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense. This includes standard functions, and others specified by format attributes (see Function Attributes), in the printf, scanf, strftime and strfmon (an X/Open extension, not in the C standard) families (or other target-specific families). Which functions are checked without format attributes having been specified depends on the standard version selected, and such checks of functions without the attribute specified are disabled by -ffreestanding or -fno-builtin.
The formats are checked against the format features supported by GNU libc version 2.2. These include all ISO C90 and C99 features, as well as features from the Single Unix Specification and some BSD and GNU extensions. Other library implementations may not support all these features; GCC does not support warning about features that go beyond a particular library's limitations. However, if -pedantic is used with -Wformat, warnings will be given about format features not in the selected standard version (but not for strfmon formats, since those are not in any version of the C standard). See Options Controlling C Dialect.
It looks like the GCC manual does provide a way to do this with a #pragma, actually (contrary to what Aiden Bell says):
6.62.13 Diagnostic Pragmas
E.g., for the -Wuninitialized warning, you can do...
#pragma GCC diagnostic ignored "-Wuninitialized"
... to suppress the warning, or...
#pragma GCC diagnostic warning "-Wuninitialized"
... to treat it as a warning (not an error) even if you're building with -Werror.
I used the following CFLAGS:
-Wall -Wformat=0
I presume you are looking for the
#ifdef WIN32
#pragma warning (disable: #num of the warning)
#endif
Equivalent in GCC...
You can search for options such as -Wno-conversion -Wno-format-security that do the job in 3.8 Options to Request or Suppress Warnings.
But in terms of the #pragma directive:
I quote from the GCC mailing list from Google:
GCC does not, currently, provide the #pragma facility you are looking for.
Do not lose hope! There are viable
alternatives.
The first best way to fix the code so
it no longer emits the warning. Alas,
you've stated you cannot do this. :-(
NOTE: Have warnings turned up as
verbose as your team can tolerate!
[see below]
The next best way to ignore the
undesired warning is to post-process
the output of GCC to a script (such as
a Perl script) that strips out the
specific, exact warning you want to
ignore.
The next way to ignore the undesired
warning is to disable the warning for
that translation unit.
-Wno-foozle-mcgoogle, just for that particular translation unit. That's a
mighty big hammer, though. And if the
warning is in a header file, it may be
pervasive throughout your entire
project -- to which I'd direct you to
the post-processing script solution
(assuming you are disallowed from
fixing the code).
So currently no, there is no #pragma directive to disable specific warnings. Rather than using -Wall you could turn on as many warnings as you can minus specific ones.
http://www.network-theory.co.uk/docs/gccintro/gccintro_31.html
Or fix the code

Resources