By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,075 Members | 957 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,075 IT Pros & Developers. It's quick & easy.

eliminating unreferenced parameter warnings

P: n/a
void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not
be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p)
{
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with. However a
third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers. On my
compiler this will produce a useless assignment warning, so for that reason
I obviously prefer my approach.

What's your favourite trick and why? Which approach do you think is more
likely to prevent a warning? Has anyone done a survey?

Nov 14 '05 #1
Share this Question
Share on Google+
22 Replies


P: n/a
On 2005-02-01 21:11:32 -0500, "John Fisher" <fa****@nospam.com> said:
void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not
be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.
[snip]
What's your favourite trick and why? Which approach do you think is more
likely to prevent a warning? Has anyone done a survey?


I typically just delete the parameter name if I'm not actually using it:

void f(int)
{
}

--
Clark S. Cox, III
cl*******@gmail.com

Nov 14 '05 #2

P: n/a
"John Fisher" <fa****@nospam.com> wrote in message
news:11***************@proxy.nec.com.au...
void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p)
{
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with. However a
third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers. On my
compiler this will produce a useless assignment warning,
The warning is telling you that what's 'useless' is your parameter
declaration (because it's not used). I suppose the warning is so that
you'll double check to see if you meant to write the parameter
name, but misspelled it as some other name that's in scope.
I think this warning can be quite useful in that case.

so for that reason
I obviously prefer my approach.

What's your favourite trick and why?
I typically won't define arguments which I won't use.

However, if I did (perhaps I'm wanting to compile before
I've completed the function body), I'd probably do one of:

void f(int)
{
/* etc */
}

or

void f(int p)
{
p;
/* etc */
}
Which approach do you think is more
likely to prevent a warning?
I can't say without knowing which compiler(s)
are involved.
Has anyone done a survey?


I doubt it. It's a very trivial issue.

-Mike
Nov 14 '05 #3

P: n/a
Clark S. Cox III <cl*******@gmail.com> writes:
I typically just delete the parameter name if I'm not actually using it:

void f(int)
{
}


That's not C.
--
"It wouldn't be a new C standard if it didn't give a
new meaning to the word `static'."
--Peter Seebach on C99
Nov 14 '05 #4

P: n/a
John Fisher wrote:
void f(int p) {
}

Many (most?) compilers will report that p is unreferenced here.
This may not be a problem as f(int) may have to match some common prototype.
Typically, pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p) {
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with.
However, a third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers.
On my compiler, this will produce a useless assignment warning
so, for that reason, I obviously prefer my approach.

What's your favourite trick and why?
Which approach do you think is more likely to prevent a warning?
Has anyone done a survey?


You obviously have too much time on your hands.
Warning messages are supposed to be ignored if your code is correct.
Usually, there is an option to silence these warnings
if the verbosity conceals other more important errors and warnings.
Nov 14 '05 #5

P: n/a
I'm talking about situations where you can't delete the parameter, because
the function must match a common prototype e.g. in addition to my first
example

void g(int p)
{
/* Use p */
}

and

{
void (*fp)(int);
int i;

/* Assign a value to i */

/* In some circumstances we have */
fp = f;

/* Other circumstances we have */
fp = g;

/* All circumstances we have */
fp(i);
}

Apologies if I didn't make myself clear the first time
void f(int p)
{
p;
/* etc */
}
Some compilers will give a useless expression warning in this situation,
thats why I cast to void in the macro
I doubt it. It's a very trivial issue.


Getting rid of pointless warnings is important because it makes it less much
less likely that important warnings will be overlooked.

Nov 14 '05 #6

P: n/a

"John Fisher" <fa****@nospam.com> wrote in message
news:11***************@proxy.nec.com.au...
I'm talking about situations where you can't delete the parameter, because
the function must match a common prototype e.g. in addition to my first
example

void g(int p)
{
/* Use p */
}

and

{
void (*fp)(int);
int i;

/* Assign a value to i */

/* In some circumstances we have */
fp = f;

/* Other circumstances we have */
fp = g;

/* All circumstances we have */
fp(i);
}

Apologies if I didn't make myself clear the first time
void f(int p)
{
p;
/* etc */
}
Some compilers will give a useless expression warning in this situation,
thats why I cast to void in the macro
I doubt it. It's a very trivial issue.


Getting rid of pointless warnings is important because it makes it less

much less likely that important warnings will be overlooked.


IMO every warning merits attention. I wouldn't let
the fact that I might consider some to be pointless
cause me to adopt the same attitude for other warnings.

The point I was trying to make is that the warning you
mention can indeed disclose a true problem (e.g. the
'misspelling' error I mentioned).

Once I determined that the warning is indeed about something innocuous,
I wouldn't have a problem with writing:

void func(int p)
{
(void)p;
/* etc */
}

But I'd include a comment indicating the reason (and I
wouldn't hide things with a macro).

-Mike
Nov 14 '05 #7

P: n/a
> Warning messages are supposed to be ignored if your code is correct.

That's one option, but in my experience almost all warnings can easily be
eliminated and should be because it makes it less likely that important
warnings are overlooked.
Usually, there is an option to silence these warnings


If I used an option to turn warnings off, or even a class of warnings off,
then important warnings might be missed.

The point of the macro is to suppress these warnings on an individual basis.
I have seen quite widespread use of this idea. Some compilers recognize a
special comment /*ARGSUSED*/ to prevent this particular warning, but of
course thats extremely compiler specific.
Nov 14 '05 #8

P: n/a

"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:k3*****************@newsread3.news.pas.earthl ink.net...
void f(int)
{
/* etc */
}


Oops, this is not valid for C. (it is for C++
-- my mind is suffering from 'cross-language pollution'.) :-)

-Mike
Nov 14 '05 #9

P: n/a
John Fisher wrote:
Warning messages are supposed to be ignored if your code is correct.
That's one option but, in my experience,
almost all warnings can easily be eliminated and should be
because it makes it less likely
that important warnings are overlooked.


That's understood.
But you have gone beyond that.
You are not fixing questionable code.
You are inserting implementation specific code
(always a dubious practice)
just to shut-up a verbose compiler.
Usually, there is an option to silence these warnings
If I used an option to turn warnings off, or even a class of warnings off,
then important warnings might be missed.


That's what I said.
Study your compiler warning options.
They may allow you to silence just the warnings
about code that you know is correct.
The point of the macro is to suppress these warnings on an individual basis.
I have seen quite widespread use of this idea.
Some compilers recognize a special comment /*ARGSUSED*/
to prevent this particular warning
but, of course, that's extremely compiler specific.


Don't cobble your code just to appease an inferior compiler.
Your code will be more portable,
if you avoid implementation specific features.

It isn't practical or even desirable to silence all warnings.
They are warnings and not errors so that you can ignore them
if you know that your code is correct.
Nov 14 '05 #10

P: n/a
John Fisher wrote:

void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not
be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p)
{
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with. However a
third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers. On my
compiler this will produce a useless assignment warning, so for that reason
I obviously prefer my approach.
If you use enough compilers, you'll find one that warns against just
about any simple construct you care to invent. One way to avoid such
warnings, however, is to use the parameter, in such a way that the
compiler can't (easily) tell you're just kidding. (See below.)

And then, if you want to, use the preprocessor to define it away for
production code.


What's your favourite trick and why? Which approach do you think is more
likely to prevent a warning? Has anyone done a survey?


My favourite trick is:

#ifndef NDEBUG
void Sink(void *p)
{
static int i;
if(i == 0)
{
i = 1;
Sink(p);
}
}
#else
#define Sink(x)
#endif

int f(int p)
{
/* definitions go here */

Sink(&p);

/* code goes here */
}
Nov 14 '05 #11

P: n/a
In article <ct**********@nntp1.jpl.nasa.gov>, E.**************@jpl.nasa.gov
says...
Some compilers recognize a special comment /*ARGSUSED*/
to prevent this particular warning
but, of course, that's extremely compiler specific.


Don't cobble your code just to appease an inferior compiler.
Your code will be more portable,
if you avoid implementation specific features.


Care to explain how using a comment block as shown above could
impact portability? It may not have the desired result on
every compiler (making the warning go away), but I can't think
of a situation in which it would not compile as a result of
using that comment. Can you?

--
Randy Howard (2reply remove FOOBAR)
Nov 14 '05 #12

P: n/a
On Tue, 01 Feb 2005 20:46:21 -0800, E. Robert Tisdale wrote:
John Fisher wrote:
void f(int p) {
}

Many (most?) compilers will report that p is unreferenced here.
This may not be a problem as f(int) may have to match some common prototype.
Typically, pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))
By defining a macro you can easily change it to whatever is apporpriate to
the compiler you are using. Even if you don't it doesn't make the code
incorrect for other compilers.

so that

void f(int p) {
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with.
However, a third party code vendor uses

#define UNUSED(p) { (p) = (p); }
I would prefer

#define UNUSED(p) ((p) = (p))

although it doesn't matter that much in the context where this should be
used.
I believe this code has been ported to many different compilers.
On my compiler, this will produce a useless assignment warning
so, for that reason, I obviously prefer my approach.

What's your favourite trick and why?
Which approach do you think is more likely to prevent a warning?
Has anyone done a survey?

If you're worried about this just make a couple of choices available in
the header that defines UNUSED().
You obviously have too much time on your hands.
Warning messages are supposed to be ignored if your code is correct.
It would be even better if warning messages didn't exist if your code is
correct. For anybody else who has to maintain your code subsequently
warnings need to be checked. And even for code I wrote I don't want to
have to weed out the genuine errors from the "spurious" warnings each time
I compile something.
Usually, there is an option to silence these warnings
if the verbosity conceals other more important errors and warnings.


The point is that the same warning could indicate a genuine error in some
circumstances. Just disabling warnings or classes of warnings is not a
sensible solution to this.

Lawrence

Nov 14 '05 #13

P: n/a
On Wed, 02 Feb 2005 02:11:32 GMT, John Fisher
<fa****@nospam.com> wrote:
What's your favourite trick and why? Which approach do you think is more
likely to prevent a warning? Has anyone done a survey?


#pragma unused x

is the cleanest I've seen. But that is supported even less than the
other methods (x=x; and (void)x;) unfortunately. Both the redundant
assignment and the cast to void tend to give "statement doesn't do
anything" type errors on various compilers.

Of course, any compiler can give any diagnostics it likes and still be
compliant ("Error 9999: this code is rubbish!") for any or no reason, as
long as it still compiles a valid program...

Chris C
Nov 14 '05 #14

P: n/a
Randy Howard wrote:
E.**************@jpl.nasa.gov says...
Some compilers recognize a special comment /*ARGSUSED*/
to prevent this particular warning
but, of course, that's extremely compiler specific.


Don't cobble your code just to appease an inferior compiler.
Your code will be more portable,
if you avoid implementation specific features.


Care to explain how using a comment block as shown above could
impact portability? It may not have the desired result on
every compiler (making the warning go away), but I can't think
of a situation in which it would not compile as a result of
using that comment. Can you?


+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT | :.:\:\:/:/:.:
|FEED THE TROLLSDALE| :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
================================================== ============

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #15

P: n/a
On Wed, 02 Feb 2005 10:07:51 +0000, Lawrence Kirby
<lk****@netactive.co.uk> wrote:
It would be even better if warning messages didn't exist if your code is
correct. For anybody else who has to maintain your code subsequently
warnings need to be checked. And even for code I wrote I don't want to
have to weed out the genuine errors from the "spurious" warnings each time
I compile something.


Exactly. Every spurious warning which has to be checked makes it less
likely that real warnings will be noticed (as in the story of the boy
who cried 'wolf'), and slows down maintenance.
Usually, there is an option to silence these warnings
if the verbosity conceals other more important errors and warnings.


The point is that the same warning could indicate a genuine error in some
circumstances. Just disabling warnings or classes of warnings is not a
sensible solution to this.


Some compilers allow warnings to be switched on or off (or back to the
default) with a #pragma in the specific part of the code. I think that
is the best solution, because it means that warnings can be disabled
only for sections where they are known to be spurious. Having a #pragma
which says "ignore just this variable if it is unused" is even better in
this case (although not necessarily in the general case).

Chris C
Nov 14 '05 #16

P: n/a
John Fisher wrote:
void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p)
{
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with. However a third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers. On my compiler this will produce a useless assignment warning, so for that reason I obviously prefer my approach.

What's your favourite trick and why? Which approach do you think is more likely to prevent a warning? Has anyone done a survey?


This is indeed not an uncommon problem.

If you only care about suppressing warnings from compilers that support
an attribute to parameters, I prefer using those compiler specific
attributes. For example you would write:

int constantEvil( int dummyArg attribute__(unused) ) { return 666; }

where attribute__ is defined something like this:

#ifdef __GNUC__
#define attribute__(a) __attribute__ ((a))
#else
#define attribute__(a)
#endif
Altering the program as such by adding spurious statements like (void)x
or x=x feels ugly regardless of the issue that it might not be
effective.
Daniel Vallstrom

Nov 14 '05 #17

P: n/a
In message <87************@benpfaff.org>
Ben Pfaff <bl*@cs.stanford.edu> wrote:
Clark S. Cox III <cl*******@gmail.com> writes:
I typically just delete the parameter name if I'm not actually using it:

void f(int)
{
}


That's not C.


Bloomin' well should be though. Just the sort of simple improvement that C++
introduced that is worth adopting.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #18

P: n/a
On 2005-02-01 23:23:32 -0500, Ben Pfaff <bl*@cs.stanford.edu> said:
Clark S. Cox III <cl*******@gmail.com> writes:
I typically just delete the parameter name if I'm not actually using it:

void f(int)
{
}


That's not C.


Ack, sorry, wrong group.

--
Clark S. Cox, III
cl*******@gmail.com

Nov 14 '05 #19

P: n/a
To summarize the discussion:
Possible methods of eliminating the warning are

1. ((void)(p))
2. ((p) = (p))
3. #pragma unused p
4. GNU C's __attribute__((unused))
5. /*ARGUSED*/

It is not known which is supported by the largest proportion of compilers.
None of these methods are 100% portable. For this reason some believe that
it is not worth doing.
A macro could be used to switch between methods 1, 2 and nothing at all, or
method 4 and nothing at all. Either don't attempt to eliminate the warning,
or find the method or combination of methods that works best for your
particular set of compilers.
Nov 14 '05 #20

P: n/a
"Kevin Bracey" <ke**********@tematic.com> wrote in message
news:79****************@tematic.com...
In message <87************@benpfaff.org>
Ben Pfaff <bl*@cs.stanford.edu> wrote:
Clark S. Cox III <cl*******@gmail.com> writes:
I typically just delete the parameter name if I'm not actually using
it:

void f(int)
{
}


That's not C.


Bloomin' well should be though. Just the sort of simple improvement that
C++ introduced that is worth adopting.


I agree. Seems useful to me.

Is there any particular problem (eg because of language grammar)? I can't
see one. I'm no C++ expert, but if there's no real problem there I would
expect the same would apply to C.

Has it been suggested and rejected? If so, does anyone know why?

Alex
Nov 14 '05 #21

P: n/a
On Thu, 03 Feb 2005 00:04:54 GMT, John Fisher
<fa****@nospam.com> wrote:
To summarize the discussion:
Possible methods of eliminating the warning are

1. ((void)(p))
2. ((p) = (p))
3. #pragma unused p
4. GNU C's __attribute__((unused))
5. /*ARGUSED*/

It is not known which is supported by the largest proportion of compilers.
None of these methods are 100% portable. For this reason some believe that
it is not worth doing.
They are all portable in that they won't produce errors (they may
increase the number of warnings, though).
A macro could be used to switch between methods 1, 2 and nothing at all, or
method 4 and nothing at all. Either don't attempt to eliminate the warning,
or find the method or combination of methods that works best for your
particular set of compilers.


Bearing in mind that none of them may work. On at least one compiler
I've used certain warnings cannot be switched off without suppressing
all warnings (or redirecting output to /dev/null, with the same effect).

I favour using #define UNUSED(var), then (a) that can be customised for
each compiler and (b) if all of the methods fail and produce more
warnings it can be defined as nothing and you're no worse off, the code
will still be self-documenting that the parameter is unused.

Chris C
Nov 14 '05 #22

P: n/a
"John Fisher" <fa****@nospam.com> writes:
void f(int p)
{
}

Many (most?) compilers will report that p is unreferenced here. This may not
be a problem as f may have to match some common prototype. Typically
pointers to functions are involved.

For a long time I have used

#define UNUSED(p) ((void)(p))

so that

void f(int p)
{
UNUSED(p);
}

will not cause a warning on all compilers I have tried it with. However a
third party code vendor uses

#define UNUSED(p) { (p) = (p); }

I believe this code has been ported to many different compilers. On my
compiler this will produce a useless assignment warning, so for that reason
I obviously prefer my approach.

What's your favourite trick and why? Which approach do you think is more
likely to prevent a warning? Has anyone done a survey?

1. If possible encapsulate in a macro;

2. My personal preference is to call the macro IGNORE;

2a. (the macro name UNUSED is misleading because it does not guarantee
that the variable is unused; IGNORE references the variable but
"ignores" it);

3. Obviously different definitions might be needed on different
platforms, but unless this definition fails I would normally use

#define IGNORE(v) ((void) &(v))

Using '&' means IGNORE can also be used with volatile variables
without causing access. Not that parameters are normally volatile,
but writing in good style is a good habit to cultivate; and, there
are times when you might want to use IGNORE on a local variable rather
than a parameter.

Of course, the '&' can cause problems if used on a 'register'
variable; IMO the positive consequences of that -- namely,
discouraging the use of 'register' -- outweigh the negative
consequences.
Nov 14 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.