For instance:
Bool NullFunc(const struct timespec *when, const char *who)
{
return TRUE;
}
In C++ I was able to put a /*...*/ comment around the parameters. But not in C of course, where it gives me the error:
error: parameter name omitted
I usually write a macro like this:
#define UNUSED(x) (void)(x)
You can use this macro for all your unused parameters. (Note that this works on any compiler.)
For example:
void f(int x) {
UNUSED(x);
...
}
In GCC, you can label the parameter with the unused attribute.
This attribute, attached to a variable, means that the variable is
meant to be possibly unused. GCC will not produce a warning for this
variable.
In practice this is accomplished by putting __attribute__ ((unused)) just before the parameter. For example:
void foo(workerid_t workerId) { }
becomes
void foo(__attribute__((unused)) workerid_t workerId) { }
You can use GCC or Clang's unused attribute. However, I use these macros in a header to avoid having GCC specific attributes all over the source, also having __attribute__ everywhere is a bit verbose/ugly.
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
#ifdef __GNUC__
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
# define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif
Then you can do...
void foo(int UNUSED(bar)) { ... }
I prefer this because you get an error if you try use bar in the code anywhere, so you can't leave the attribute in by mistake.
And for functions...
static void UNUSED_FUNCTION(foo)(int bar) { ... }
Note 1):
As far as I know, MSVC doesn't have an equivalent to __attribute__((__unused__)).
Note 2):
The UNUSED macro won't work for arguments which contain parenthesis,
so if you have an argument like float (*coords)[3] you can't do,
float UNUSED((*coords)[3]) or float (*UNUSED(coords))[3]. This is the only downside to the UNUSED macro I found so far, and in these cases I fall back to (void)coords;.
Seeing that this is marked as gcc you can use the command line switch Wno-unused-parameter.
For example:
gcc -Wno-unused-parameter test.c
Of course this effects the whole file (and maybe project depending where you set the switch) but you don't have to change any code.
With GCC with the unused attribute:
int foo (__attribute__((unused)) int bar) {
return 0;
}
A gcc/g++ specific way to suppress the unused parameter warning for a block of source code is to enclose it with the following pragma statements:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
Since C++ 17, the [[maybe_unused]] attribute can be used to suppress warnings about unused parameters.
Based on the OP's example code:
Bool NullFunc([[maybe_unused]] const struct timespec *when, [[maybe_unused]] const char *who)
{
return TRUE;
}
I got the same problem. I used a third-part library. When I compile this library, the compiler (gcc/clang) will complain about unused variables.
Like this
test.cpp:29:11: warning: variable 'magic' set but not used [-Wunused-but-set-variable]
short magic[] = {
test.cpp:84:17: warning: unused variable 'before_write' [-Wunused-variable]
int64_t before_write = Thread::currentTimeMillis();
So the solution is pretty clear. Adding -Wno-unused as gcc/clang CFLAG will suppress all "unused" warnings, even thought you have -Wall set.
In this way, you DO NOT NEED to change any code.
Labelling the attribute is ideal way. MACRO leads to sometime confusion.
and by using void(x),we are adding an overhead in processing.
If not using input argument, use
void foo(int __attribute__((unused))key)
{
}
If not using the variable defined inside the function
void foo(int key)
{
int hash = 0;
int bkt __attribute__((unused)) = 0;
api_call(x, hash, bkt);
}
Now later using the hash variable for your logic but doesn’t need bkt. define bkt as unused, otherwise compiler says'bkt set bt not used".
NOTE: This is just to suppress the warning not for optimization.
In MSVC to suppress a particular warning it is enough to specify the it's number to compiler as /wd#. My CMakeLists.txt contains such the block:
If (MSVC)
Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
Add_definitions (-Wall -W -pedantic)
Else ()
Message ("Unknown compiler")
Endif ()
Now I can not say what exactly /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127 mean, because I do not pay any attention to MSVC for three years, but they suppress superpedantic warnings that does not influence the result.
I've seen this style being used:
if (when || who || format || data || len);
For the record, I like Job's answer, but I'm curious about a solution just using the variable name by itself in a "do-nothing" statement:
void foo(int x) {
x; /* unused */
...
}
Sure, this has drawbacks; for instance, without the "unused" note it looks like a mistake rather than an intentional line of code.
The benefit is that no DEFINE is needed and it gets rid of the warning.
Related
There are a ton of questions about suppressing "variable set but not used" warnings, but I haven't found one that addresses my very specific problem, which is a debugging macro defined as follows:
#ifdef DEBUG
# define dbg_printf(...) ((void)printf(__VA_ARGS__))
#else
# define dbg_printf(...) ((void)( /* ??? */ ))
#endif
A variable that is set unconditionally, and then used only as one of the arguments to dbg_printf, should not trigger "variable set but not used" warnings, whether or not DEBUG is defined. It should not be necessary to annotate such variables at the point of definition. For example, this should be warning-free:
struct Thing { int value; struct Thing *next; };
struct Thing *find_first_match(int n, struct Thing *list)
{
struct Thing *p;
int searched = 0;
for (p = list; p; p = p->next) {
searched++;
if (p->value == n) break;
}
dbg_printf("%s: %s after scanning %d entries\n",
__func__, p ? "found" : "not found", searched);
return p;
}
I have tried a couple things in place of the /* ??? */, but nothing I have tried so far has worked without undesirable side effects:
# define dbg_printf(...) ((void)(0 && (__VA_ARGS__)))
Causes some versions of clang to complain about unused values, e.g.
void foo(void) {
dbg_printf("%d\n", 23);
}
⟶
test.c:4:14: warning: expression result unused [-Wunused-value]
dbg_printf("%d\n", 23);
^~~~~~
# define dbg_printf(...) ((void)(sizeof(__VA_ARGS__)))
Causes some versions of clang to complain about misuse of sizeof, e.g. same test case
test.c:4:14: warning: sizeof on pointer operation will return size of 'const char *'
instead of 'const char [4]' [-Wsizeof-array-decay]
dbg_printf("%d\n", 23);
^~~~~~
[Edited to add:] An inline variadic function that does nothing, instead of a macro, e.g.
static inline void dbg_printf(const char *msg, ...) {
(void)msg;
}
is no good because its arguments will still be evaluated for their
side effects, and the offending code base has lots of instances of
stuff like
// code that mutates a global data structure, and then ...
dbg_printf("validation status after %s: %s\n", __func__,
expensive_global_data_structure_validation());
Please suggest a construct that can be used in place of the /* ??? */ that will suppress "variable set but not used" warnings without introducing other spurious diagnostics in their place. If this can be done with strictly conforming C2011 code, that is preferable. Compiler extensions are acceptable if and only if they work correctly on all four of:
gcc 4.8
gcc 9.x
clang 7.0
clang 10.0
Yes, we are stuck using old compilers for good reasons, or at least reasons which nobody has the spare cycles to overcome.
I use this trick to disable such warnings:
#ifdef DEBUG
# define dbg_printf(...) ((void)printf(__VA_ARGS__))
#else
# define dbg_printf(...) do { if ((0)) (void)printf(__VA_ARGS__); } while (0)
#endif
This macro generates no code in optimized builds but does not complain about variables initialized and only used inside the argument list.
I use do { ... } while (0) to encapsulate the if statement in a block so the macro can be used as a regular function call in a context where a single statement is needed such as this:
if (something_went_wrong())
dbg_printf("something went wrong\n");
else
keep_going();
I write the test if ((0)) with a double pair or parentheses to avoid a warning on constant expression always false and/or unreachable code. clang would issue a warning about unreachable code with -Weverything (which includes -Wunreachable-code). They recommend the use of redundant parentheses to silence this warning in contexts where it is the programmer's intent.
do { } while (0) does not trigger this warning because it is a classic idiom to group statements as a single statement.
The {} are redundant to, the macro could be simplified as:
#define dbg_printf(...) do if((0))(void)printf(__VA_ARGS__);while(0)
The same goal can be reached with a simpler logical expression, that may or may not trigger other compiler warnings:
#define dbg_printf(...) ((void)(((0)) && printf(__VA_ARGS__)))
This will work:
#ifdef DEBUG
# define dbg_printf(...) ((void)printf(__VA_ARGS__))
#else
# define dbg_printf(...) ((void)(0 && printf(__VA_ARGS__)))
#endif
As the right-hand side of the && operator won't be evaluated.
Alternately:
#ifdef DEBUG
# undef DEBUG
# define DEBUG 1
#else
# define DEBUG 0
#endif
Then:
#define dbg_printf(...) ((void)(DEBUG && printf(__VA_ARGS__)))
That way you have if multiple such definitions depending on DEBUG you only need a single #ifdef.
For instance:
Bool NullFunc(const struct timespec *when, const char *who)
{
return TRUE;
}
In C++ I was able to put a /*...*/ comment around the parameters. But not in C of course, where it gives me the error:
error: parameter name omitted
I usually write a macro like this:
#define UNUSED(x) (void)(x)
You can use this macro for all your unused parameters. (Note that this works on any compiler.)
For example:
void f(int x) {
UNUSED(x);
...
}
In GCC, you can label the parameter with the unused attribute.
This attribute, attached to a variable, means that the variable is
meant to be possibly unused. GCC will not produce a warning for this
variable.
In practice this is accomplished by putting __attribute__ ((unused)) just before the parameter. For example:
void foo(workerid_t workerId) { }
becomes
void foo(__attribute__((unused)) workerid_t workerId) { }
You can use GCC or Clang's unused attribute. However, I use these macros in a header to avoid having GCC specific attributes all over the source, also having __attribute__ everywhere is a bit verbose/ugly.
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
#ifdef __GNUC__
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
# define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif
Then you can do...
void foo(int UNUSED(bar)) { ... }
I prefer this because you get an error if you try use bar in the code anywhere, so you can't leave the attribute in by mistake.
And for functions...
static void UNUSED_FUNCTION(foo)(int bar) { ... }
Note 1):
As far as I know, MSVC doesn't have an equivalent to __attribute__((__unused__)).
Note 2):
The UNUSED macro won't work for arguments which contain parenthesis,
so if you have an argument like float (*coords)[3] you can't do,
float UNUSED((*coords)[3]) or float (*UNUSED(coords))[3]. This is the only downside to the UNUSED macro I found so far, and in these cases I fall back to (void)coords;.
Seeing that this is marked as gcc you can use the command line switch Wno-unused-parameter.
For example:
gcc -Wno-unused-parameter test.c
Of course this effects the whole file (and maybe project depending where you set the switch) but you don't have to change any code.
With GCC with the unused attribute:
int foo (__attribute__((unused)) int bar) {
return 0;
}
A gcc/g++ specific way to suppress the unused parameter warning for a block of source code is to enclose it with the following pragma statements:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
Since C++ 17, the [[maybe_unused]] attribute can be used to suppress warnings about unused parameters.
Based on the OP's example code:
Bool NullFunc([[maybe_unused]] const struct timespec *when, [[maybe_unused]] const char *who)
{
return TRUE;
}
I got the same problem. I used a third-part library. When I compile this library, the compiler (gcc/clang) will complain about unused variables.
Like this
test.cpp:29:11: warning: variable 'magic' set but not used [-Wunused-but-set-variable]
short magic[] = {
test.cpp:84:17: warning: unused variable 'before_write' [-Wunused-variable]
int64_t before_write = Thread::currentTimeMillis();
So the solution is pretty clear. Adding -Wno-unused as gcc/clang CFLAG will suppress all "unused" warnings, even thought you have -Wall set.
In this way, you DO NOT NEED to change any code.
Labelling the attribute is ideal way. MACRO leads to sometime confusion.
and by using void(x),we are adding an overhead in processing.
If not using input argument, use
void foo(int __attribute__((unused))key)
{
}
If not using the variable defined inside the function
void foo(int key)
{
int hash = 0;
int bkt __attribute__((unused)) = 0;
api_call(x, hash, bkt);
}
Now later using the hash variable for your logic but doesn’t need bkt. define bkt as unused, otherwise compiler says'bkt set bt not used".
NOTE: This is just to suppress the warning not for optimization.
In MSVC to suppress a particular warning it is enough to specify the it's number to compiler as /wd#. My CMakeLists.txt contains such the block:
If (MSVC)
Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
Add_definitions (-Wall -W -pedantic)
Else ()
Message ("Unknown compiler")
Endif ()
Now I can not say what exactly /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127 mean, because I do not pay any attention to MSVC for three years, but they suppress superpedantic warnings that does not influence the result.
I've seen this style being used:
if (when || who || format || data || len);
For the record, I like Job's answer, but I'm curious about a solution just using the variable name by itself in a "do-nothing" statement:
void foo(int x) {
x; /* unused */
...
}
Sure, this has drawbacks; for instance, without the "unused" note it looks like a mistake rather than an intentional line of code.
The benefit is that no DEFINE is needed and it gets rid of the warning.
Given the following code in a project I'm working on:
/* Pre-definitions in a pre-definitions file to be included in the project */
#ifdef WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__
#endif
/* My definitions */
#define MAC() \
MAC1()
#define MAC1() \
myPrintFunction(__FUNCNAME__)
/* My print function */
void myPrintFunction(const char * functionName)
{
printf("\n func name: %s \n",functionName);
}
/* Macro usage example function */
void myFunction()
{
if (some_condition)
{
MAC();
}
}
The function name is presented as an empty string.
Any idea why, and how can I fix it?
Code compiled and tested on Linux machine, using GCC compiler.
Use __func__ out of the box. It's been part of the C standard since C99. Change your compiler settings to use at least that standard.
Note that __func__ is not a macro but a predefined identifier which takes the form such that writing it anywhere within a function body is exactly equivalent to using it at that point, having first written
static const char __func__[] = "function-name";
just after the opening brace of a function body.
Formally the behaviour of your current code is undefined. Any symbol containing two consecutive underscores is reserved by the system. (That includes macro names, function names, and variable names.)
Your code as presented gives the expected result (once I'd added the necessary includes and main):
#include <stdio.h>
#ifdef WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__
#endif
/* My definitions */
#define MAC() \
MAC1()
#define MAC1() \
myPrintFunction(__FUNCNAME__)
void myPrintFunction(const char * functionName)
{
printf("\n func name: %s \n",functionName);
}
int main()
{
MAC();
}
I compiled this using gcc -std=c11 -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds with no warnings.
You should really post a complete (but minimal) example that actually compiles, along with the compiler flags you used, as something must certainly be different to explain the symptoms you describe.
Also, when writing statements as macros, you may find it helpful to use the do {...} while (0) idiom to avoid unexpected expansions changing the control flow.
when i try to include a .h file which consists of definition for inline functions as
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SLA (int32_t o1, int32_t o2, int32_t o3)
it is giving the "warning: always_inline function might not be inlinable [-Wattributes]" can you somebody help me i am struggling to fix it.
For functions declared inline(!!!!), this attribute inlines the function independent of any restrictions that otherwise apply to inlining.
So, when you set the attribute without declaring the function inline you will get these warning. Declare the function additionally inline will void these warnings. Behavior gnu gcc/g++ 5.30
# define FORCE_INLINE __attribute__((always_inline)) inline
FORCE_INLINE vec3 operator- (vec3 a, vec3 b) { vec3 t = { a.x-b.x, a.y-b.y, a.z-b.z }; return t; }
finally, after spending two days efforts found the solution as it is below
it is just because of a compiler(arm-none-eabi-gcc) option in Makefile
CFLAGS= -D inline if this flag is set, it throws warning as __attribute__( ( always_inline ) ) __STATIC_INLINE(inline) uint32_t __SLA (int32_t o1, int32_t o2, int32_t o3) when trying to include a .h file which consists of always inline functions
What that warning is saying is that the compiler, is not always happy accepting your function as inline, or it wants it to be declared as inline.
I guess it's that __attribute__ ((always_inline)) implies inline - in which case the parsing of the attribute needs to set DECL_DECLARED_INLINE_P.
The GCC manual specifies
always_inline Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level is specified.
Here's the gcc test for the revision
__attribute__ ((always_inline)) does not imply "inline" in gcc. If you use __attribute__ ((always_inline)) without also using "inline" then you will see this gcc warning message, unless it is disabled:
warning: 'always_inline' function might not be inlinable
In the original post I suspect that __STATIC_INLINE(inline) is intended to expand to static inline.
There may be other reasons why the function cannot be inlined, for example if it is recursive.
We have a function macro #define FOO(arg) foo(arg) with int foo(const char* bar);. When NDEBUG is defined FOO is defined as #define FOO(arg) 0, however this causes many compiler warnings because in many cases FOO's return value is not used. The solution should work with with ANSI C compilers and cause no warnings. I've tried:
(void)0: can't be assigend to variable
static int foo(const char* bar) { return 0; } : causes unused static function warning in some modules
static inline int foo(const char* bar) { return 0; } : only works with C99 compilers
Thanks for your help!
edit1:
It's somewhat like a trace macro and used all over the project. Mostly it's just used as a statement like FOO("function x called");, but in a few cases I saw if (FOO("condition a")) { /* some more debug output */ }. With NDEBUG defined and optimization enabled nothing should be left of FOO. I didn't come up with this, but I have to clean up this mess :).
edit2: I should add that for gcc release builds these flags are used: -O3 -Wall -ansi
edit3: For now I'm going with __inline int dummy() { return 0; }. __inline works with both VisualC and GCC in ansi mode.
I guess it's a little bit compiler dependent but this should work:
#ifndef NDEBUG
#define FOO(arg) foo(arg)
#else
#define FOO(arg) ((int)0)
#endif
It prevents the "expression has no effect" warning, it does nothing and its value when used is still 0.
EDITED
It seems it's something not so portable so (now) you have these conditions:
(0) or ((int)0) work at least on VC 2010.
__noop should work on any version of VC after 2003.
VC6 is not a problem because it doesn't emit the C4555 warning at all. For other compilers you may use:
((void)0, 0) It may work on a lot of compilers (maybe it's the more portable one?).
inline int foo(const char* bar) { return 0; } works with any other C99 compiler (as you wrote you may need to declare it as static on gcc).
For any other prehistoric C compiler use the solution pointed by #Jobs: abs(0)
What you could do to prevent the warning is the following:
#ifndef NDEBUG
#define FOO(arg) foo(arg)
#else
#define FOO(arg) abs(0)
#endif
I'm not saying this is ideal (you'd have to make sure stdlib.h is included everywhere, for example) but it does prevent the warning.
I'd do something that is dependent on the C version. In the header file:
#if __STDC_VERSION__ > 199900L
inline int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif
in one compilation unit
#if __STDC_VERSION__ < 199900L
int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif
or use for the oldish C version something like Job's answer, that is a function that is certain to be optimized out but that doesn't produce the warning.