EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Suppressing "Parameter not used" Warning

Started by Dave Hansen October 3, 2005
"Old Wolf" <oldwolf@inspire.net.nz> writes:
> Dave Hansen wrote: >> In another group, a poster asked about defining a macro NOT_USED as >> shown above to quiet the compiler warning. His suggested >> implementation was >> >> #define NOT_USED(p) ((void)(p)) >> >> In this particular case, he noted the compiler he was using would >> generate the warning even in the presence of this macro. I suggested >> he use >> >> #define NOT_USED(p) ((p)=(p)) >> >> >> So I'm curious. Which form (if either) is more common? Are there >> any implementations that will generate executable code for the latter? > > Yes, the compiler might warn that 'p' is assigned a value which > is never used. And it might also warn about reading an uninitialized > variable.
In fact, strictly speaking, this could invoke undefined behavior if p really hasn't been initialized. Since it's a parameter (at least in the context intended by the OP), that would happen only if the caller passes an uninitialized value, so it would require some additional smarts by the compiler to detect the problem. On most real-world systems, this isn't going to cause any visible problems, but it's possible that certain pointer values can cause a trap when you try to load them into a register, even if there's no attempt to dereference the value. The same could apply to any type that can have trap representations. Hiding this behind a NOT_USED macro is a good idea. The definition of the macro can probably be made to vary depending on what system you're on, using the usual twisty maze of #ifdefs method. The ((p)=(p)) trick is ok if you make sure p is always initialized, even to a meaningless value. As others have mentioned, there is no portable way to control specific warnings that will work across implementations. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this.
In article <1128377419.771778.219560@g47g2000cwa.googlegroups.com>, 
oldwolf@inspire.net.nz says...
> Dave Hansen wrote: > > In another group, a poster asked about defining a macro NOT_USED as > > shown above to quiet the compiler warning. His suggested > > implementation was > > > > #define NOT_USED(p) ((void)(p)) > > > > In this particular case, he noted the compiler he was using would > > generate the warning even in the presence of this macro. I suggested > > he use > > > > #define NOT_USED(p) ((p)=(p)) > > > > > > So I'm curious. Which form (if either) is more common? Are there > > any implementations that will generate executable code for the latter? > > Yes, the compiler might warn that 'p' is assigned a value which > is never used. And it might also warn about reading an uninitialized > variable. > > One compiler I use has this definition: > > #define NOT_USED(junk) { (volatile typeof(junk))junk = junk; } > >
Metrowerks Codewarrior has the #pragma unused (varname) construct to solve this problem. I'm surprised that other compilers don't have the same facility. Mark Borgerson
Dave Hansen wrote:

> Often when writing code requiring function pointers, it is necessary > to write functions that ignore their formal parameters. For example, > a state machine function might take a status input, but a certain > error-handling state might ignore it: > > typedef void (*State_Fn)(uint8_t); > > void error_state(uint8_t status) > { > NOT_USED(status); > > /* code handling error but ignoring status */ > } > > In another group, a poster asked about defining a macro NOT_USED as > shown above to quiet the compiler warning. His suggested > implementation was > > #define NOT_USED(p) ((void)(p)) > > In this particular case, he noted the compiler he was using would > generate the warning even in the presence of this macro.
I have used a void cast for some compilers. For another, I was successful with #define UNUSED(x) if(x); Thad
"David Brown" <david@westcontrol.removethisbit.com> wrote in message
news:43417a0a$1@news.wineasy.se...
...
> > #define NOT_USED(p) ((void)(p))
...
> I use the first version, a cast-to-void macro. It works fine for gcc > (various ports).
Also: borland, watcom, a few less popilar ones. I don't remember about msvc++. Probably too. Alex
"Thad Smith" <ThadSmith@acm.org> wrote in message
news:4341e5ff$0$27319$892e0abb@auth.newsreader.octanews.com...
...
> I have used a void cast for some compilers. For another, I was > successful with > > #define UNUSED(x) if(x);
Nice, though some clever compiler could warn here whether or not you're sure it's what you intend to do, whether or not this code has any effect. Alex
Mark Borgerson wrote:
> In article <1128377419.771778.219560@g47g2000cwa.googlegroups.com>, > oldwolf@inspire.net.nz says... > >>Dave Hansen wrote: >> >>>In another group, a poster asked about defining a macro NOT_USED as >>>shown above to quiet the compiler warning. His suggested >>>implementation was >>> >>> #define NOT_USED(p) ((void)(p)) >>> >>>In this particular case, he noted the compiler he was using would >>>generate the warning even in the presence of this macro. I suggested >>>he use >>> >>> #define NOT_USED(p) ((p)=(p)) >>> >>> >>>So I'm curious. Which form (if either) is more common? Are there >>>any implementations that will generate executable code for the latter? >> >>Yes, the compiler might warn that 'p' is assigned a value which >>is never used. And it might also warn about reading an uninitialized >>variable. >> >>One compiler I use has this definition: >> >> #define NOT_USED(junk) { (volatile typeof(junk))junk = junk; } >> >> > > Metrowerks Codewarrior has the > > #pragma unused (varname) > > construct to solve this problem. I'm surprised that other compilers > don't have the same facility. > > Mark Borgerson
The trouble with such pragmas is that they are completely non-portable. As Grant Edwards said, gcc has an equivalent (using an attribute, which is gcc prefers over pragmas). Often non-portability is not a problem, since there are so many other non-portable aspects to typical embedded systems (and in the case of gcc, it is at least portable to a few dozen other gcc ports).
Grant Edwards wrote:
> On 2005-10-03, David Brown <david@westcontrol.removethisbit.com> wrote: > > >>> #define NOT_USED(p) ((void)(p)) >>>[...] >>> #define NOT_USED(p) ((p)=(p)) >>>[...] >>> >>>So I'm curious. Which form (if either) is more common? Are there any >>>implementations that will generate executable code for the latter? > > >>I use the first version, a cast-to-void macro. It works fine >>for gcc (various ports). > > > Very slightly OT, but I just use gcc's __attribute__((unused)). > I realize it's not-portable to other compilers, but... > > 1) In my applications so much of the code is platform-specific > that it just doesn't matter. > > 2) I've used nothing but gcc for embedded work for the past 6 > or 7 years anyway. >
Also OT, but the warning that bugs me most with gcc is "warning: will never be executed" on code that gets removed by the optimiser. If I've written code that really cannot ever be executed, it's (almost certainly) a mistake, so I want the compiler to tell me. But on code like this: if (test()) { doThis(); doThat(); } else { doSomethingElse(); doThat(); } gcc will combine the two "doThat()" calls (which is good), and then warn that one of the "will never be executed", which is bad. If you know any good ideas to get working "will never be executed" warnings, even if it is "wait for gcc 4.1.x", I'd love to hear them.
"Dave Hansen" <iddw@hotmail.com> wrote in message 
news:1128348834.7e34f2c71121565d6e8683d1777b7524@teranews...
> Please note crosspost. >
snip snip void error_state(uint8_t /* status */) I prefer to leave the argument there as it should make code easier to comprehend. Commenting it out does not need comments.
Bill Davy wrote:
> "Dave Hansen" <iddw@hotmail.com> wrote in message > news:1128348834.7e34f2c71121565d6e8683d1777b7524@teranews... > >>Please note crosspost. > > snip snip > > void error_state(uint8_t /* status */) > > I prefer to leave the argument there as it should make code easier to > comprehend. Commenting it out does not need comments.
As noted by an earlier poster, that is not valid for a C function definition (declaration yes, but not definition which is what was being discussed). If you want to discus what you do in C++ (or any language other than C) then please remove comp.lang.c from the crosspost. -- Flash Gordon Living in interesting times. Although my email address says spam, it is real and I read it.
David Brown wrote:
> if (test()) { > doThis(); > doThat(); > } else { > doSomethingElse(); > doThat(); > } > > gcc will combine the two "doThat()" calls (which is good), and then warn > that one of the "will never be executed", which is bad. > > If you know any good ideas to get working "will never be executed" > warnings, even if it is "wait for gcc 4.1.x", I'd love to hear them.
Hmmm. I tried this with a couple of GCC versions at default and -O[23] optimization levels (cross and native) and saw no such warning. What options/versions are you using? -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144 http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." The Eagles, "Already Gone" The Beatles were wrong: 1 & 1 & 1 is 1

Memfault Beyond the Launch