Suppressing "Parameter not used" Warning

Please note crosspost.

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 suggested he use

#define NOT_USED(p) ((p)=(p))

He was pleased that it worked, but was concerned that the former implementation was more widely supported, and that the latter might generate executable code. I for one had never seen the former before, though I've often seen the latter (usually not hidden behind a macro), and I've never seen it actually generate code. At least, not in the last ten years or so.

So I'm curious. Which form (if either) is more common? Are there any implementations that will generate executable code for the latter?

Thanks, -=Dave

-=Dave

--
Change is inevitable, progress is not.
Reply to
Dave Hansen
Loading thread data ...

Non executable code tends to generate warnings.

In distributions file for a sort timing program my distribution function arguments are of this form: (e_type *array, size_t n, long unsigned *seed)

but only some of them use the seed for a PRNG.

Others are like this:

void sorted(e_type *a, size_t n, long unsigned *seed) { a += n; while (n-- != 0) { (*--a).data = n; } seed; }

So, I just make an expression statement out of seed and that seems to stop the warnings.

--
pete
Reply to
pete

Why not just

void error_state( uint8_t ) /* don't care about formal parameter */ { /* code */ }

? (I'm not enough of a guru to answer your real question.)

--
Christopher Benson-Manica  | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org    | don't, I need to know.  Flames welcome.
Reply to
Christopher Benson-Manica

Because that's not legal C. If it were, we obviously wouldn't need any hacks. You can do this in prototypes; in C++ you can also do it in definitions. Not in C, however.

S.

Reply to
Skarmander

Dave Hansen wrote On 10/03/05 10:13,:

First, there is no sure-fire way to prevent compilers from issuing diagnostics. The compiler is entitled to grouse about anything it chooses, provided it accepts code that does not actually contravene the Standard. It can warn about spellnig errors in comennts, or about inconsistent indentation levels. The requirement "No warnings from any compiler" is not ultimately tenable.

FWIW, the `(void)p' formulation seems to be widespread. Even if a compiler complains about it, a human reader will see immediately that it was in fact the programmer's intent that `p' remain unused -- the programmer may have made a mistake, but at least it was not one of simple inattention.

I don't think `(p)=(p)' is a wonderful idea. If `p' is volatile the generated code must perform both the read and the write. If `p' is `const' the compiler is required to issue a diagnostic, so you're no better off than when you started -- worse, if anything. Of course, `const'-qualified function parameters are fairly unusual and `volatile' parameters are exceedingly rare, but the possibilities exist.

In any case, hiding the actual trickery behind a NOT_USED macro seems a good idea: you can re-#define NOT_USED as part of your adaptation to each new compiler that comes along, using whatever compiler-specific dodge seems to work best.

--
Eric.Sosman@sun.com
Reply to
Eric Sosman

An alternative would be to invoke the compiler using a flag or option that disables the unused variable/parameter warning.

However, it's good practice to turn the warning back on every once in a while and see if any unexpected unused thingies have crept into the code.

Reply to
Anonymous 7843

I use the first version, a cast-to-void macro. It works fine for gcc (various ports).

Reply to
David Brown

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.
--
Grant Edwards                   grante             Yow!  Will the third world
                                  at               war keep "Bosom Buddies"
 Click to see the full signature
Reply to
Grant Edwards

My apologies; I use C++, and this was a difference of which I was not aware. Thanks.

--
Christopher Benson-Manica  | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org    | don't, I need to know.  Flames welcome.
Reply to
Christopher Benson-Manica

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; }

Reply to
Old Wolf

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  
San Diego Supercomputer Center               
 Click to see the full signature
Reply to
Keith Thompson

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

Reply to
Mark Borgerson

I have used a void cast for some compilers. For another, I was successful with

#define UNUSED(x) if(x);

Thad

Reply to
Thad Smith

...

Also: borland, watcom, a few less popilar ones. I don't remember about msvc++. Probably too. Alex

Reply to
Alexei A. Frounze

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

Reply to
Alexei A. Frounze

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).

Reply to
David Brown

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.

Reply to
David Brown

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.

Reply to
Bill Davy

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.
 Click to see the full signature
Reply to
Flash Gordon

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
 Click to see the full signature
Reply to
Michael N. Moran

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.