Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #42189 > unrolled thread

Table of "safe" methods to suppress "unused parameter" warnings?

Started bymathog <dmathog@gmail.com>
First post2014-03-26 09:54 -0700
Last post2014-06-11 02:04 -0700
Articles 20 on this page of 46 — 17 participants

Back to article view | Back to comp.lang.c


Contents

  Table of "safe" methods to suppress "unused parameter" warnings? mathog <dmathog@gmail.com> - 2014-03-26 09:54 -0700
    Re: Table of "safe" methods to suppress "unused parameter" warnings? Barry Schwarz <schwarzb@dqel.com> - 2014-03-26 10:55 -0700
      Re: Table of "safe" methods to suppress "unused parameter" warnings? Keith Thompson <kst-u@mib.org> - 2014-03-26 11:13 -0700
      Re: Table of "safe" methods to suppress "unused parameter" warnings? Javier Lopez <j.lopezg@aol.com> - 2014-03-26 19:45 +0100
        Re: Table of "safe" methods to suppress "unused parameter" warnings? Kaz Kylheku <kaz@kylheku.com> - 2014-03-26 19:55 +0000
    Re: Table of "safe" methods to suppress "unused parameter" warnings? mathog <dmathog@gmail.com> - 2014-03-26 17:01 -0700
      Re: Table of "safe" methods to suppress "unused parameter" warnings? Javier Lopez <j.lopezg@aol.com> - 2014-03-27 01:46 +0100
        Re: Table of "safe" methods to suppress "unused parameter" warnings? Thomas Jahns <jahns@idontlikespam.dkrz.de> - 2014-03-27 09:34 +0100
          Re: Table of "safe" methods to suppress "unused parameter" warnings? gazelle@shell.xmission.com (Kenny McCormack) - 2014-03-27 10:52 +0000
          Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-27 13:10 +0100
    Re: Table of "safe" methods to suppress "unused parameter" warnings? Ian Collins <ian-news@hotmail.com> - 2014-03-27 21:50 +1300
      Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 17:32 -0700
        Re: Table of "safe" methods to suppress "unused parameter" warnings? Ian Collins <ian-news@hotmail.com> - 2014-03-31 09:31 +1300
          Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-31 11:31 +0200
            Re: Table of "safe" methods to suppress "unused parameter" warnings? Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2014-03-31 12:04 +0200
              Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-31 13:55 +0200
                Re: Table of "safe" methods to suppress "unused parameter" warnings? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2014-04-01 02:04 +0300
                  Re: Table of "safe" methods to suppress "unused parameter" warnings? Kaz Kylheku <kaz@kylheku.com> - 2014-03-31 23:37 +0000
                    Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-04-01 10:16 +0200
                    Re: Table of "safe" methods to suppress "unused parameter" warnings? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2014-05-22 13:10 +0300
                      Re: Table of "safe" methods to suppress "unused parameter" warnings? Kaz Kylheku <kaz@kylheku.com> - 2014-05-22 12:05 +0000
                  Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-04-01 09:59 +0200
            Re: Table of "safe" methods to suppress "unused parameter" warnings? Ian Collins <ian-news@hotmail.com> - 2014-03-31 23:17 +1300
              Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-31 14:05 +0200
            Re: Table of "safe" methods to suppress "unused parameter" warnings? Kaz Kylheku <kaz@kylheku.com> - 2014-03-31 15:24 +0000
          Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-04-15 04:26 -0700
            Re: Table of "safe" methods to suppress "unused parameter" warnings? Öö Tiib <ootiib@hot.ee> - 2014-04-23 07:31 -0700
              Re: Table of "safe" methods to suppress "unused parameter" warnings? Keith Thompson <kst-u@mib.org> - 2014-04-23 08:45 -0700
    Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-03-29 17:21 -0700
      Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-31 13:26 +0200
        Re: Table of "safe" methods to suppress "unused parameter" warnings? James Kuyper <jameskuyper@verizon.net> - 2014-03-31 07:37 -0400
          Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-03-31 14:12 +0200
        Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-04-18 07:00 -0700
          Re: Table of "safe" methods to suppress "unused parameter" warnings? gazelle@shell.xmission.com (Kenny McCormack) - 2014-04-18 15:02 +0000
          Re: Table of "safe" methods to suppress "unused parameter" warnings? Keith Thompson <kst-u@mib.org> - 2014-04-18 08:58 -0700
            Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-04-27 08:11 -0700
              Re: Table of "safe" methods to suppress "unused parameter" warnings? gazelle@shell.xmission.com (Kenny McCormack) - 2014-04-27 15:26 +0000
                Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-06-10 08:30 -0700
                  Re: Table of "safe" methods to suppress "unused parameter" warnings? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2014-06-11 00:57 +0300
                    Re: Table of "safe" methods to suppress "unused parameter" warnings? Ike Naar <ike@iceland.freeshell.org> - 2014-06-10 22:12 +0000
                      Re: Table of "safe" methods to suppress "unused parameter" warnings? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2014-06-11 20:25 +0300
                    Re: Table of "safe" methods to suppress "unused parameter" warnings? Martin Shobe <martin.shobe@yahoo.com> - 2014-06-10 18:59 -0500
                    Re: Table of "safe" methods to suppress "unused parameter" warnings? Tim Rentsch <txr@alumni.caltech.edu> - 2014-06-11 21:22 -0700
              Re: Table of "safe" methods to suppress "unused parameter" warnings? Kaz Kylheku <kaz@kylheku.com> - 2014-04-28 01:40 +0000
          Re: Table of "safe" methods to suppress "unused parameter" warnings? David Brown <david.brown@hesbynett.no> - 2014-04-19 17:52 +0200
    Re: Table of "safe" methods to suppress "unused parameter" warnings? Siri Crews <chine.bleu@yahoo.com> - 2014-06-11 02:04 -0700

Page 1 of 3  [1] 2 3  Next page →


#42189 — Table of "safe" methods to suppress "unused parameter" warnings?

Frommathog <dmathog@gmail.com>
Date2014-03-26 09:54 -0700
SubjectTable of "safe" methods to suppress "unused parameter" warnings?
Message-ID<lgv0nu$8g1$1@dont-email.me>
Sometimes the same parameter list must be passed to a lot of different 
functions, and some of those will not use all of the parameters, 
resulting in some compilers emitting "unused parameter" warnings.  Here 
are all of the methods I have found so far for suppressing these:

This first set of UNUSED's are applied where the parameters are declared 
in the function, as in

    int function( UNUSED(x)){

#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif

The main problem with these is that the method only works for compilers 
and tools that define a way to ignore the extra parameter in this 
manner.  It also ruins the readability of the function declarations.

This second set of UNUSED's is more general and it is applied within the 
function like:

    int function (x){
       UNUSED(x);

#define UNUSED(x) ((void)x)
#define UNUSED(x) x=x
#define UNUSED(x) ( *(volatile typeof(x) *)&(x) = (x); )
#define UNUSED(x) if(x);

Unfortunately the members of the second set tend to convert the "unused 
parameter" message into some variant of a "this line does nothing" 
message on other compilers.   For instance, that is what the "x=x" form, 
which works with gcc does when clang sees it.

What I'm wondering is if any of you have a table of compiler 
identification macros vs. members of the second set, that can be used in 
a header file to pick the appropriate method for each compiler, so that 
compilation with the strictest warnings is silent about unused 
parameters.  Like this (this example is entirely made up, I am NOT 
saying that the associations below are correct):

#if defined (__GNUC__)
#define UNUSED(x) x=x
#elif defined (__CLANG__)
#define UNUSED(x) ((void)x)
#elif defind (__INTELC__)
#define UNUSED(x) ( *(volatile typeof(x) *)&(x) = (x); )
/* etc. */
#endif

There is one other method I know of, which is to actually use the 
parameter "harmlessly", but it has its own issues.  For instance to do

    extern unsigned int junk;

and within the function

    if(x)junk++;

With junk defined globally in the c file that holds main().  If the 
compiler only sees one module at a time it cannot tell if junk will ever 
be used, so it should not give any warnings.  If the program is a single 
file though, or all modules are compiled together, the compiler will be 
able to detect that nothing is actually happening and issue warnings to 
that effect.


Thanks,

David Mathog

[toc] | [next] | [standalone]


#42193

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-03-26 10:55 -0700
Message-ID<7m46j9dd8q1qdrlce8oj57u66bnqp3f4cm@4ax.com>
In reply to#42189
If the parameter x is not a function pointer, why not use the simpler
    (void)x;

If x is a function pointer, a couple of options come to mind
    (void*)x;
or
   if (0) x(appropriate dummy arguments);
or if the compiler generates a diagnostic for the if expression being
constant then you could use an expression you know to be false but the
compiler would not, such as
   if (agrc < 0) x(...);

On Wed, 26 Mar 2014 09:54:13 -0700, mathog <dmathog@gmail.com> wrote:

>Sometimes the same parameter list must be passed to a lot of different 
>functions, and some of those will not use all of the parameters, 
>resulting in some compilers emitting "unused parameter" warnings.  Here 
>are all of the methods I have found so far for suppressing these:
>
>This first set of UNUSED's are applied where the parameters are declared 
>in the function, as in
>
>    int function( UNUSED(x)){
>
>#ifdef UNUSED
>#elif defined(__GNUC__)
># define UNUSED(x) UNUSED_ ## x __attribute__((unused))
>#elif defined(__LCLINT__)
># define UNUSED(x) /*@unused@*/ x
>#else
># define UNUSED(x) x
>#endif
>
>The main problem with these is that the method only works for compilers 
>and tools that define a way to ignore the extra parameter in this 
>manner.  It also ruins the readability of the function declarations.
>
>This second set of UNUSED's is more general and it is applied within the 
>function like:
>
>    int function (x){
>       UNUSED(x);
>
>#define UNUSED(x) ((void)x)
>#define UNUSED(x) x=x
>#define UNUSED(x) ( *(volatile typeof(x) *)&(x) = (x); )
>#define UNUSED(x) if(x);
>
>Unfortunately the members of the second set tend to convert the "unused 
>parameter" message into some variant of a "this line does nothing" 
>message on other compilers.   For instance, that is what the "x=x" form, 
>which works with gcc does when clang sees it.
>
>What I'm wondering is if any of you have a table of compiler 
>identification macros vs. members of the second set, that can be used in 
>a header file to pick the appropriate method for each compiler, so that 
>compilation with the strictest warnings is silent about unused 
>parameters.  Like this (this example is entirely made up, I am NOT 
>saying that the associations below are correct):
>
>#if defined (__GNUC__)
>#define UNUSED(x) x=x
>#elif defined (__CLANG__)
>#define UNUSED(x) ((void)x)
>#elif defind (__INTELC__)
>#define UNUSED(x) ( *(volatile typeof(x) *)&(x) = (x); )
>/* etc. */
>#endif
>
>There is one other method I know of, which is to actually use the 
>parameter "harmlessly", but it has its own issues.  For instance to do
>
>    extern unsigned int junk;
>
>and within the function
>
>    if(x)junk++;
>
>With junk defined globally in the c file that holds main().  If the 
>compiler only sees one module at a time it cannot tell if junk will ever 
>be used, so it should not give any warnings.  If the program is a single 
>file though, or all modules are compiled together, the compiler will be 
>able to detect that nothing is actually happening and issue warnings to 
>that effect.
>
>
>Thanks,
>
>David Mathog

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#42194

FromKeith Thompson <kst-u@mib.org>
Date2014-03-26 11:13 -0700
Message-ID<lneh1olter.fsf@nuthaus.mib.org>
In reply to#42193
Barry Schwarz <schwarzb@dqel.com> writes:
> If the parameter x is not a function pointer, why not use the simpler
>     (void)x;
>
> If x is a function pointer, a couple of options come to mind
>     (void*)x;
> or
>    if (0) x(appropriate dummy arguments);
> or if the compiler generates a diagnostic for the if expression being
> constant then you could use an expression you know to be false but the
> compiler would not, such as
>    if (agrc < 0) x(...);
[...]

The

    (void)x;

version is perfectly valid whether x is a function pointer or not.

BTW, argc, assuming it's the conventional first argument to main,
isn't visible outside main, unless you've declared something with
that name yourself.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#42195

FromJavier Lopez <j.lopezg@aol.com>
Date2014-03-26 19:45 +0100
Message-ID<lgv79v$17p$1@speranza.aioe.org>
In reply to#42193
El 26/03/2014 18:55, Barry Schwarz escribió:
> If the parameter x is not a function pointer, why not use the simpler
>      (void)x;
This works for pointer to function, at least on gcc 4.6.3.

>
> If x is a function pointer, a couple of options come to mind
>      (void*)x;
> or
>     if (0) x(appropriate dummy arguments);
> or if the compiler generates a diagnostic for the if expression being
> constant then you could use an expression you know to be false but the
> compiler would not, such as
>     if (agrc < 0) x(...);
Unless you don't care about CPU cycles, it's better to see a compiler 
warning than to write code the compiler cannot optimize out.

[toc] | [prev] | [next] | [standalone]


#42196

FromKaz Kylheku <kaz@kylheku.com>
Date2014-03-26 19:55 +0000
Message-ID<20140326120503.999@kylheku.com>
In reply to#42195
On 2014-03-26, Javier Lopez <j.lopezg@aol.com> wrote:
> El 26/03/2014 18:55, Barry Schwarz escribió:
>> If the parameter x is not a function pointer, why not use the simpler
>>      (void)x;
> This works for pointer to function, at least on gcc 4.6.3.

(void) x  works even if x is a struct. Though the standard doesn't seem
to spell it out, any expression can be converted to void, which results
in a "void expression" that is evaluated for its side effects only.

Also, the void type is the only non-scalar type that may be used in a cast.
Furthermore, the constraint that the operand be scalar does not apply
if the cast is to (void).

[toc] | [prev] | [next] | [standalone]


#42198

Frommathog <dmathog@gmail.com>
Date2014-03-26 17:01 -0700
Message-ID<lgvpp5$jod$1@dont-email.me>
In reply to#42189
Here is a small example program to test these methods on
various compilers.  The results I found follow the program.
(I don't have access to all that many compilers, and some of them are
very old.)

---cut here -- test_unused.c --
#include <stdlib.h>
#include <stdio.h>

#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif


void method1(int x){
    (void) x;
    printf("method 1\n");
}

void method2(int x){
    x = x;
    printf("method 2\n");
}

void method3(int x){
    *(volatile typeof(x) *) &(x) = (x);
    printf("method 3\n");
}

void method4(int x){
    if(x){};
    printf("method 4\n");
}

void method5(int UNUSED(x)){
    printf("method 5\n");
}

int main(void){
    method1(1);
    method2(1);
    method3(1);
    method4(1);
    method5(1);
    exit(EXIT_SUCCESS);
}
---cut here ----

Results:

(gcc 4.6.3 and 4.7.2 tested, they did the same thing)
gcc -Wall -Wextra --std=c99 -o test_unused test_unused.c
    warns:
    test_unused.c: In function 'method3':
    test_unused.c:24:4: error: unknown type name 'typeof'
    test_unused.c:24:22: error: expected ')' before 'x'
    test_unused.c:24:25: error: expected ')' before '*' token

gcc -Wall -Wextra -o test_unused test_unused.c
    no warnings

(Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on 
LLVM 3.0))
clang -Wall -o test_unused test_unused.c
    warns:
   test_unused.c:20:6: warning: explicitly assigning a variable
   of type 'int' to itself [-Wself-assign]
    x = x;
    ~ ^ ~

(A very old version of the intel linux compiler == 9.0)
iccbin -Wall -std=c99 -gcc-version=340 -i-static \
     -o test_unused test_unused.c
  warns about "external definition with no prior declaration" for all
  of the functions, but did not warn about anything else.

(A very old version of the Sun Forte Developer 7.0 C 5.4
on an equally old Sparc)
cc -o test_unused test_unused.c
   warns:
"test_unused.c", line 25: warning: no explicit type given
"test_unused.c", line 25: syntax error before or at: typeof
"test_unused.c", line 29: type specifier can not be used as array size 
expression qualifier
"test_unused.c", line 29: warning: no explicit type given
"test_unused.c", line 29: cannot recover from previous errors

And that's all the compilers I have to test.


Regards,

David Mathog






[toc] | [prev] | [next] | [standalone]


#42199

FromJavier Lopez <j.lopezg@aol.com>
Date2014-03-27 01:46 +0100
Message-ID<lgvsf0$krb$1@speranza.aioe.org>
In reply to#42198
> (gcc 4.6.3 and 4.7.2 tested, they did the same thing)
> gcc -Wall -Wextra --std=c99 -o test_unused test_unused.c
>     warns:
>     test_unused.c: In function 'method3':
>     test_unused.c:24:4: error: unknown type name 'typeof'
>     test_unused.c:24:22: error: expected ')' before 'x'
>     test_unused.c:24:25: error: expected ')' before '*' token
typeof is a GNU C extension, so enabling c99 disables GNU extensions
see http://gcc.gnu.org/onlinedocs/gcc/Typeof.html

> (A very old version of the intel linux compiler == 9.0)
> iccbin -Wall -std=c99 -gcc-version=340 -i-static \
>      -o test_unused test_unused.c
>   warns about "external definition with no prior declaration" for all
>   of the functions, but did not warn about anything else.
>
This goes away if you forward-declare the functions.

> (A very old version of the Sun Forte Developer 7.0 C 5.4
> on an equally old Sparc)
> cc -o test_unused test_unused.c
>    warns:
> "test_unused.c", line 25: warning: no explicit type given
> "test_unused.c", line 25: syntax error before or at: typeof
> "test_unused.c", line 29: type specifier can not be used as array size
> expression qualifier
> "test_unused.c", line 29: warning: no explicit type given
> "test_unused.c", line 29: cannot recover from previous errors
>
See above

> And that's all the compilers I have to test.
You should be using (void)x regardless the compiler as any of them 
accept it and can optimize that out.


[toc] | [prev] | [next] | [standalone]


#42205

FromThomas Jahns <jahns@idontlikespam.dkrz.de>
Date2014-03-27 09:34 +0100
Message-ID<lh0nqe$4id$1@gwdu112.gwdg.de>
In reply to#42199
On 03/27/14 01:46, Javier Lopez wrote:
> typeof is a GNU C extension, so enabling c99 disables GNU extensions
> see http://gcc.gnu.org/onlinedocs/gcc/Typeof.html

I've found __typeof to be reasonably portable (supported by gcc, xlc, pgcc and icc).

Thomas

[toc] | [prev] | [next] | [standalone]


#42212

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2014-03-27 10:52 +0000
Message-ID<lh0vtt$u6u$2@news.xmission.com>
In reply to#42205
In article <lh0nqe$4id$1@gwdu112.gwdg.de>,
Thomas Jahns  <jahns@idontlikespam.dkrz.de> wrote:
>On 03/27/14 01:46, Javier Lopez wrote:
>> typeof is a GNU C extension, so enabling c99 disables GNU extensions
>> see http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
>
>I've found __typeof to be reasonably portable (supported by gcc, xlc, pgcc and icc).
>
>Thomas
>

In comp.lang.c, there is no such thing as "reasonably" portable.

(The old saw about being "sorta pregnant" comes to mind...)

-- 
I've been watching cat videos on YouTube.  More content and closer to
the truth than anything on Fox.

[toc] | [prev] | [next] | [standalone]


#42215

FromDavid Brown <david.brown@hesbynett.no>
Date2014-03-27 13:10 +0100
Message-ID<lh14gb$4lf$1@dont-email.me>
In reply to#42205
On 27/03/14 09:34, Thomas Jahns wrote:
> On 03/27/14 01:46, Javier Lopez wrote:
>> typeof is a GNU C extension, so enabling c99 disables GNU extensions
>> see http://gcc.gnu.org/onlinedocs/gcc/Typeof.html
> 
> I've found __typeof to be reasonably portable (supported by gcc, xlc, pgcc and icc).
> 
> Thomas
> 

Even if typeof is accepted by the compiler, the usage here is /really/
bad - it forces a volatile write to the function's parameter which will
undoubtedly generate extra code, and may force a number of additional
effects such as blocked optimisations, copying of register parameters
into a stack frame (which may in itself force the use of a stack frame
that could otherwise be omitted), etc.

It also means that if you have more sophisticated optimisation at play,
such as inlining, function cloning, etc., then you will make a mess with
such extra volatile accesses.

The simple "(void) x" should work on all compilers and produce no effect
on the code.

[toc] | [prev] | [next] | [standalone]


#42206

FromIan Collins <ian-news@hotmail.com>
Date2014-03-27 21:50 +1300
Message-ID<bpi725FabtcU4@mid.individual.net>
In reply to#42189
mathog wrote:
> Sometimes the same parameter list must be passed to a lot of different
> functions, and some of those will not use all of the parameters,
> resulting in some compilers emitting "unused parameter" warnings.  Here
> are all of the methods I have found so far for suppressing these:

I wonder why C doesn't just follow C++ and allow unnamed parameters?

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#42340

FromTim Rentsch <txr@alumni.caltech.edu>
Date2014-03-29 17:32 -0700
Message-ID<kfnioqwil03.fsf@x-alumni2.alumni.caltech.edu>
In reply to#42206
Ian Collins <ian-news@hotmail.com> writes:

> mathog wrote:
>> Sometimes the same parameter list must be passed to a lot of different
>> functions, and some of those will not use all of the parameters,
>> resulting in some compilers emitting "unused parameter" warnings.  Here
>> are all of the methods I have found so far for suppressing these:
>
> I wonder why C doesn't just follow C++ and allow unnamed parameters?

Assuming for the sake of discussion that C did this, it
still doesn't solve the problem, because sometimes you
want the parameter name there but still have it not used,
eg, when a function body has multiple definitions under
control of a C preprocessor conditional.  And there are
variables besides parameter names that are important to
mark UNUSED in certain circumstances.

[toc] | [prev] | [next] | [standalone]


#42366

FromIan Collins <ian-news@hotmail.com>
Date2014-03-31 09:31 +1300
Message-ID<bprd8bFfrepU2@mid.individual.net>
In reply to#42340
Tim Rentsch wrote:
> Ian Collins <ian-news@hotmail.com> writes:
>
>> mathog wrote:
>>> Sometimes the same parameter list must be passed to a lot of different
>>> functions, and some of those will not use all of the parameters,
>>> resulting in some compilers emitting "unused parameter" warnings.  Here
>>> are all of the methods I have found so far for suppressing these:
>>
>> I wonder why C doesn't just follow C++ and allow unnamed parameters?
>
> Assuming for the sake of discussion that C did this, it
> still doesn't solve the problem, because sometimes you
> want the parameter name there but still have it not used,
> eg, when a function body has multiple definitions under
> control of a C preprocessor conditional.

I disagree.  Allowing unnamed parameters would address the exact problem 
stated in the question.  I don't see how multiple definitions under 
control of a C preprocessor conditional would make a difference.  If an 
"unused" parameter is used in the function body, you have a bug waiting 
to happen.  It would be better to have it unnamed to allow the compiler 
to spot the mistake.

If you turn the argument on its head, why does C require parameters to 
be named?  There doesn't appear to be any logical reason for this rule.

> And there are
> variables besides parameter names that are important to
> mark UNUSED in certain circumstances.

I assume you are referring to unused function return values?  I don't 
see how this is relevant to the original question.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#42389

FromDavid Brown <david.brown@hesbynett.no>
Date2014-03-31 11:31 +0200
Message-ID<lhbcla$14u$1@dont-email.me>
In reply to#42366
On 30/03/14 22:31, Ian Collins wrote:
> Tim Rentsch wrote:
>> Ian Collins <ian-news@hotmail.com> writes:
>>
>>> mathog wrote:
>>>> Sometimes the same parameter list must be passed to a lot of different
>>>> functions, and some of those will not use all of the parameters,
>>>> resulting in some compilers emitting "unused parameter" warnings.  Here
>>>> are all of the methods I have found so far for suppressing these:
>>>
>>> I wonder why C doesn't just follow C++ and allow unnamed parameters?
>>
>> Assuming for the sake of discussion that C did this, it
>> still doesn't solve the problem, because sometimes you
>> want the parameter name there but still have it not used,
>> eg, when a function body has multiple definitions under
>> control of a C preprocessor conditional.
> 
> I disagree.  Allowing unnamed parameters would address the exact problem
> stated in the question.  I don't see how multiple definitions under
> control of a C preprocessor conditional would make a difference.  If an
> "unused" parameter is used in the function body, you have a bug waiting
> to happen.  It would be better to have it unnamed to allow the compiler
> to spot the mistake.
> 
> If you turn the argument on its head, why does C require parameters to
> be named?  There doesn't appear to be any logical reason for this rule.

I disagree (at least a bit) here - I don't see any reason to have
unnamed parameters in C.  If the parameter is completely useless, then
it should be removed entirely - if not, then the name is part of the
documentation for the function's interface.  Just because it is not used
in this particular version of the implementation of the function, does
not mean it should not be named.

And the solution to the original problem is nothing more dramatic than
"(void) x;", which is neither hard to write nor hard to understand.

In C++, I can think of a situation where unnamed parameters make sense -
you might want a function that requires you to have an object of a
particular class but does not care about the contents.  This can be used
to give compile-time checking of constraints.  For example, if your
system has a global interrupt lock, then you might use a class
"InterruptDisabler" whose constructor preserves the old interrupt state
and disables interrupts, and whose destructor restores the state.  A
function that expects interrupts to be disabled could take an unnamed
parameter of type "const InterruptDisabler&".



> 
>> And there are
>> variables besides parameter names that are important to
>> mark UNUSED in certain circumstances.
> 
> I assume you are referring to unused function return values?  I don't
> see how this is relevant to the original question.
> 

[toc] | [prev] | [next] | [standalone]


#42390

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2014-03-31 12:04 +0200
Message-ID<87d2h2lm5p.fsf@dpt-info.u-strasbg.fr>
In reply to#42389
David Brown <david.brown@hesbynett.no> writes:

> On 30/03/14 22:31, Ian Collins wrote:
>> Tim Rentsch wrote:

>>>> mathog wrote:
>>>>> Sometimes the same parameter list must be passed to a lot of different
>>>>> functions, and some of those will not use all of the parameters,
>>>>> resulting in some compilers emitting "unused parameter" warnings.

>> I disagree.  Allowing unnamed parameters would address the exact problem
>> stated in the question.

> I disagree (at least a bit) here - I don't see any reason to have
> unnamed parameters in C.  If the parameter is completely useless, then
> it should be removed entirely - if not, then the name is part of the
> documentation for the function's interface.

I think the OP mentionned callbacks (see above, I hope I have the
quoting right), where the interface is imposed. Typically, GUI toolkits
make massive use of this, but pthread_create is another example---there
are cases where a thread does not take a parameter, and relies on shared
data only.

I've had this situation often, I would like to see unnamed parameters in
C (a simple comment solves the "documentation issue").

> And the solution to the original problem is nothing more dramatic than
> "(void) x;", which is neither hard to write nor hard to understand.

Agree. It is still somewhat strange to insert a statement with no
effect.

> In C++, I can think of a situation where unnamed parameters make sense -
> you might want a function that requires you to have an object of a
> particular class but does not care about the contents. [...]

Not only. Virtual member functions are a (fairly frequent) variant of
the "callback" approach.

> This can be used to give compile-time checking of constraints. For
> example, if your system has a global interrupt lock, then you might
> use a class "InterruptDisabler" whose constructor preserves the old
> interrupt state and disables interrupts, and whose destructor restores
> the state. A function that expects interrupts to be disabled could
> take an unnamed parameter of type "const InterruptDisabler&".

Not sure about your last sentence... And the whole idea seems rather,
well, unusual.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#42395

FromDavid Brown <david.brown@hesbynett.no>
Date2014-03-31 13:55 +0200
Message-ID<lhbl31$sld$1@dont-email.me>
In reply to#42390
On 31/03/14 12:04, Alain Ketterlin wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 30/03/14 22:31, Ian Collins wrote:
>>> Tim Rentsch wrote:
> 
>>>>> mathog wrote:
>>>>>> Sometimes the same parameter list must be passed to a lot of different
>>>>>> functions, and some of those will not use all of the parameters,
>>>>>> resulting in some compilers emitting "unused parameter" warnings.
> 
>>> I disagree.  Allowing unnamed parameters would address the exact problem
>>> stated in the question.
> 
>> I disagree (at least a bit) here - I don't see any reason to have
>> unnamed parameters in C.  If the parameter is completely useless, then
>> it should be removed entirely - if not, then the name is part of the
>> documentation for the function's interface.
> 
> I think the OP mentionned callbacks (see above, I hope I have the
> quoting right), where the interface is imposed. Typically, GUI toolkits
> make massive use of this, but pthread_create is another example---there
> are cases where a thread does not take a parameter, and relies on shared
> data only.

I missed that bit - sometimes threads in c.l.c. get so long that I have
to skip many details.

But you are right - that /is/ a good reason to have unnamed parameters
in C.  If you have to fit a function into a particular general function
type, then you will sometimes be forced to have parameters that are
never used, and typically have generic names like "param1" in the
function type declaration - leaving them unnamed in the function
definition would be clear documentation that they are never used in that
particular function.

So I'll make a minor U-turn and say that unnamed parameters in C /would/
sometimes be a useful feature.

> 
> I've had this situation often, I would like to see unnamed parameters in
> C (a simple comment solves the "documentation issue").
> 
>> And the solution to the original problem is nothing more dramatic than
>> "(void) x;", which is neither hard to write nor hard to understand.
> 
> Agree. It is still somewhat strange to insert a statement with no
> effect.

True, but without any standard way of handling this then "(void) x;" is
the simplest and clearest way to have a statement with no effect.

> 
>> In C++, I can think of a situation where unnamed parameters make sense -
>> you might want a function that requires you to have an object of a
>> particular class but does not care about the contents. [...]
> 
> Not only. Virtual member functions are a (fairly frequent) variant of
> the "callback" approach.
> 
>> This can be used to give compile-time checking of constraints. For
>> example, if your system has a global interrupt lock, then you might
>> use a class "InterruptDisabler" whose constructor preserves the old
>> interrupt state and disables interrupts, and whose destructor restores
>> the state. A function that expects interrupts to be disabled could
>> take an unnamed parameter of type "const InterruptDisabler&".
> 
> Not sure about your last sentence... And the whole idea seems rather,
> well, unusual.
> 

I think the idea is perhaps unusual - and it is certainly heretic in
c.l.c.  If you haven't done embedded development, then the idea of
"disabling interrupts" is probably a bit odd.  But let's take another
example.  Suppose you have some sort of lock, with two functions
"getBigLock()" and "releaseBigLock()":

extern void getBigLock(void);
extern void releaseBigLock(void);

// Don't call this unless you've got the big lock!
extern void doSomethingDangerous(void);

void foo(void) {
	getBigLock();
	doSomethingDangerous();
	releaseBigLock();
}

void bar(void) {
	doSomethingDangerous();
}


In this case, the compiler cannot help spot that bar() is going to cause
trouble - you are reliant on comments and programmer care to get the
locking right.

In C++, you could do this:

class BigLock {
public:
	BigLock() { getBigLock(); }
	~BigLock() { releaseBigLock(); }
}

extern void doSomethingDangerous(const BigLock&);

void foo(void) {
	BigLock bl;
	doSomethingDangerous(bl);
}

void bar(void) {
	doSomethingDangerous();
}

bar() is now clearly a compile-time error.  doSomethingDangerous()
doesn't actually do anything with the parameter - it just uses
type-checking to ensure that you have a BigLock.

With enough care, templates, and hierarchies, you can do quite a bit of
compile-time checking using types like this.



[toc] | [prev] | [next] | [standalone]


#42426

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2014-04-01 02:04 +0300
Message-ID<878urqnf6j.fsf@bazspaz.fatphil.org>
In reply to#42395
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> David Brown <david.brown@hesbynett.no> writes:
> >True, but without any standard way of handling this then "(void) x;" is
> >the simplest and clearest way to have a statement with no effect.
> 
>   Actually (I admit that I might take your sentence out of its
>   context here), when »x« is a variable, »x;« is the simplest
>   and clearest way to have a statement with no effect that
>   mentions this variable »x«, and, otherwise, »;« is the
>   simplest and clearest way to have a statement with no effect.

But it's the "(void)" part that most clearly says "this is
not supposed to do have no effect", IMHO. The intention is
not to just have no effect, it's to be clearly deliberate too.

Phil
-- 
Religion is too important a matter to its devotees to be a subject of 
ridicule. If they indulge in absurdities, they are to be pitied rather
than ridiculed. -- Immanuel Kant (1724-1804), lecture at Konigsberg, 1775

[toc] | [prev] | [next] | [standalone]


#42430

FromKaz Kylheku <kaz@kylheku.com>
Date2014-03-31 23:37 +0000
Message-ID<20140331161218.168@kylheku.com>
In reply to#42426
On 2014-03-31, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>> David Brown <david.brown@hesbynett.no> writes:
>> >True, but without any standard way of handling this then "(void) x;" is
>> >the simplest and clearest way to have a statement with no effect.
>> 
>>   Actually (I admit that I might take your sentence out of its
>>   context here), when »x« is a variable, »x;« is the simplest
>>   and clearest way to have a statement with no effect that
>>   mentions this variable »x«, and, otherwise, »;« is the
>>   simplest and clearest way to have a statement with no effect.
>
> But it's the "(void)" part that most clearly says "this is
> not supposed to do have no effect", IMHO. The intention is
> not to just have no effect, it's to be clearly deliberate too.

The intention of (void) E is exactly the opposite: it states
that E is to be evaluated for its side effects, and its side effects
only---the result value is to be discarded.

This is spelled out in ISO C.

  6.3.2.2 void

  The (nonexistent) value of a void expression (an expression that has type
  void) shall not be used in any way, and implicit or explicit conversions
  (except to void) shall not be applied to such an expression. If an expression
  of any other type is evaluated as a void expression, its value or designator
  is discarded.  (A void expression is evaluated for its side effects.)

If x is an ordinary non-volatile-qualified variable, then  "x;" has no effect,
and discards its value, and so does "(void) x;".  They are both equivalent and
nonsensical. Both of them in fact leave x unused. If a non-volatile-qualified
variable has its value accessed, but that value is immediately discarded,
that abstract use of the variable can be optimized away.

Compilers which translate "(void) x;" into the meaning "pretend that x is
used, and thereby shut up unused variable warning" are doing exactly the
following: they are giving a useful meaning to a piece of nonsense that serves
no purpose and can be optimized away completely. It is similar to a conforming
extension which gives meaning to bad syntax, except that this is
good-albeit-useless syntax.

This behavior is a hack; it should not be codified as standard behavior.
Neither x; nor (void) x; should constitute a use of x, unless x is volatile.
Thre should be no special case if that is the only evaluation of x in
a function body.

The right place for asserting that "the non-use of this variable can be
ignored"  is in the declaration of that variable. A nice way to achieve
that is the omission of a name.

Common Lisp gets this right:

  (defun foo (x y)
    (declare (ignore x) (ignorable y))
     ...)

Declare ignore means that "x is not used in the body; this is on purpose,
please don't warn about this".  If the declaration is a lie---x is in fact used
in the body---then there can be a diagnostic!

Declare ignorable means that "If x is not used in the body, that is deliberate;
please don't warn about it".  In that case, x may appear, and no diagnostic
is issued.

Ignorable is convenient for macros which might conditionally generate some
piece of code that uses a parameter, or might not. They can be simplified
by not having to conditionally add the declaration.

This would be nice to have in C:

  void foo(ignore int x, ignorable int y) { ... }

perhaps in optional conjunction with omission of the name:

  void foo(ignore int, ignorable int y) { ... }

If we ignore it; it needs no name. (In Lisp it does because the symbol
is a positional place holder in the lambda list).

[toc] | [prev] | [next] | [standalone]


#42444

FromDavid Brown <david.brown@hesbynett.no>
Date2014-04-01 10:16 +0200
Message-ID<lhdslm$sfm$1@dont-email.me>
In reply to#42430
On 01/04/14 01:37, Kaz Kylheku wrote:
> On 2014-03-31, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
>> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>> True, but without any standard way of handling this then "(void) x;" is
>>>> the simplest and clearest way to have a statement with no effect.
>>>
>>>   Actually (I admit that I might take your sentence out of its
>>>   context here), when »x« is a variable, »x;« is the simplest
>>>   and clearest way to have a statement with no effect that
>>>   mentions this variable »x«, and, otherwise, »;« is the
>>>   simplest and clearest way to have a statement with no effect.
>>
>> But it's the "(void)" part that most clearly says "this is
>> not supposed to do have no effect", IMHO. The intention is
>> not to just have no effect, it's to be clearly deliberate too.
> 
> The intention of (void) E is exactly the opposite: it states
> that E is to be evaluated for its side effects, and its side effects
> only---the result value is to be discarded.
> 
> This is spelled out in ISO C.
> 
>   6.3.2.2 void
> 
>   The (nonexistent) value of a void expression (an expression that has type
>   void) shall not be used in any way, and implicit or explicit conversions
>   (except to void) shall not be applied to such an expression. If an expression
>   of any other type is evaluated as a void expression, its value or designator
>   is discarded.  (A void expression is evaluated for its side effects.)
> 
> If x is an ordinary non-volatile-qualified variable, then  "x;" has no effect,
> and discards its value, and so does "(void) x;".  They are both equivalent and
> nonsensical. Both of them in fact leave x unused. If a non-volatile-qualified
> variable has its value accessed, but that value is immediately discarded,
> that abstract use of the variable can be optimized away.
> 
> Compilers which translate "(void) x;" into the meaning "pretend that x is
> used, and thereby shut up unused variable warning" are doing exactly the
> following: they are giving a useful meaning to a piece of nonsense that serves
> no purpose and can be optimized away completely. It is similar to a conforming
> extension which gives meaning to bad syntax, except that this is
> good-albeit-useless syntax.
> 
> This behavior is a hack; it should not be codified as standard behavior.
> Neither x; nor (void) x; should constitute a use of x, unless x is volatile.
> Thre should be no special case if that is the only evaluation of x in
> a function body.

This is all true - but since these warning messages are from the
implementation (the standards do not require them), it is perfectly
reasonable for the method of disabling them to be an
implementation-dependent "hack".  The hack here is a good choice, in
that "(void) x;" is clearly and unambiguously asking to do nothing with
x (except evaluate it, if x is volatile).  It leads to no extra object
code, is ignored by any compiler other than its effects on warning
messages, and seems to give the desired "disable the warning" effect on
most  compilers (I haven't yet seen a counterexample).

> 
> The right place for asserting that "the non-use of this variable can be
> ignored"  is in the declaration of that variable. A nice way to achieve
> that is the omission of a name.
> 

I'd agree that this makes sense too - and things like gcc's "unused"
attribute do the same thing, but in a compiler-dependent way.  Putting
the "this is not used" marker in the declaration also opens for more
optimisation, if the compiler can trust it (which it cannot for "unnamed
parameters", but could for explicitly marked unused parameters).

> Common Lisp gets this right:
> 
>   (defun foo (x y)
>     (declare (ignore x) (ignorable y))
>      ...)
> 
> Declare ignore means that "x is not used in the body; this is on purpose,
> please don't warn about this".  If the declaration is a lie---x is in fact used
> in the body---then there can be a diagnostic!
> 
> Declare ignorable means that "If x is not used in the body, that is deliberate;
> please don't warn about it".  In that case, x may appear, and no diagnostic
> is issued.
> 
> Ignorable is convenient for macros which might conditionally generate some
> piece of code that uses a parameter, or might not. They can be simplified
> by not having to conditionally add the declaration.
> 
> This would be nice to have in C:
> 
>   void foo(ignore int x, ignorable int y) { ... }
> 
> perhaps in optional conjunction with omission of the name:
> 
>   void foo(ignore int, ignorable int y) { ... }
> 
> If we ignore it; it needs no name. (In Lisp it does because the symbol
> is a positional place holder in the lambda list).
> 

That would be nice - no doubts there.  But I won't hold my breath
waiting for it to reach the C standards!

In the meantime, you can at least do this:

#if defined(__GNUC__)
#define ignorable __attribute__((unused))
#else
#define ignorable
#endif

[toc] | [prev] | [next] | [standalone]


#44805

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2014-05-22 13:10 +0300
Message-ID<8761kyjf89.fsf@bazspaz.fatphil.org>
In reply to#42430
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2014-03-31, Phil Carmody <thefatphil_demunged@yahoo.co.uk> wrote:
> > ram@zedat.fu-berlin.de (Stefan Ram) writes:
> >> David Brown <david.brown@hesbynett.no> writes:
> >> >True, but without any standard way of handling this then "(void) x;" is
> >> >the simplest and clearest way to have a statement with no effect.
> >> 
> >>   Actually (I admit that I might take your sentence out of its
> >>   context here), when »x« is a variable, »x;« is the simplest
> >>   and clearest way to have a statement with no effect that
> >>   mentions this variable »x«, and, otherwise, »;« is the
> >>   simplest and clearest way to have a statement with no effect.
> >
> > But it's the "(void)" part that most clearly says "this is
> > not supposed to do have no effect", IMHO. The intention is
> > not to just have no effect, it's to be clearly deliberate too.
> 
> The intention of (void) E is exactly the opposite: it states
> that E is to be evaluated for its side effects, and its side effects
> only---the result value is to be discarded.

Sorry for the lateness in reply. Real life too hectic.

Your response is correct. My response was still on the
original topic of "unused parameters". Alas it got later
worded as "a statement with no effect", which expanded 
the topic into general statements. So we are in complete
agreement on that point.

> This is spelled out in ISO C.
> 
>   6.3.2.2 void
> 
>   The (nonexistent) value of a void expression (an expression that has type
>   void) shall not be used in any way, and implicit or explicit conversions
>   (except to void) shall not be applied to such an expression. If an expression
>   of any other type is evaluated as a void expression, its value or designator
>   is discarded.  (A void expression is evaluated for its side effects.)
> 
> If x is an ordinary non-volatile-qualified variable, then  "x;" has no effect,
> and discards its value, and so does "(void) x;".  They are both equivalent and
> nonsensical. Both of them in fact leave x unused. If a non-volatile-qualified
> variable has its value accessed, but that value is immediately discarded,
> that abstract use of the variable can be optimized away.

You say "nonsensical", others say "decorative rather than semantic".
 
> Compilers which translate "(void) x;" into the meaning "pretend that x is
> used, and thereby shut up unused variable warning" are doing exactly the
> following: they are giving a useful meaning to a piece of nonsense that serves
> no purpose and can be optimized away completely. It is similar to a conforming
> extension which gives meaning to bad syntax, except that this is
> good-albeit-useless syntax.

Some people want to be warned about accidental lack of use of a parameter.
They have a right to request that as a feature of the compiler they chose
to use.
 
> This behavior is a hack; it should not be codified as standard behavior.

They shouldn't be codified in the C standard, certainly.

> Neither x; nor (void) x; should constitute a use of x, unless x is volatile.
> Thre should be no special case if that is the only evaluation of x in
> a function body.
> 
> The right place for asserting that "the non-use of this variable can be
> ignored"  is in the declaration of that variable.

Not always possible. Such decorations can affect the type of the
function, depending on what you want the parser to recognise.
(And often, the parser is not there to generate code, it's for
static code analysis. In fact, I have 4 C parsers on my machine, 
and only one of them is a compiler.)

> A nice way to achieve
> that is the omission of a name.

Often, yes. But alas again, it's not always possible or
even desirable. (Quality of later messages, for example.)

> Common Lisp gets this right:
> 
>   (defun foo (x y)

Doesn't look like omission of a name to me.

>     (declare (ignore x) (ignorable y))

That's not asserting that non-use can be ignored at the
point declaration of the variable either. Both of the 
things you've been positive about are not being demonstrated
here.

>      ...)
> 
> Declare ignore means that "x is not used in the body; this is on purpose,
> please don't warn about this".  If the declaration is a lie---x is in fact used
> in the body---then there can be a diagnostic!
> 
> Declare ignorable means that "If x is not used in the body, that is deliberate;
> please don't warn about it".  In that case, x may appear, and no diagnostic
> is issued.
> 
> Ignorable is convenient for macros which might conditionally generate some
> piece of code that uses a parameter, or might not. They can be simplified
> by not having to conditionally add the declaration.
> 
> This would be nice to have in C:
> 
>   void foo(ignore int x, ignorable int y) { ... }
> 
> perhaps in optional conjunction with omission of the name:
> 
>   void foo(ignore int, ignorable int y) { ... }

It gets complex because of type semantics though. In a family of
function pointers, what if some of the parameters are ignored for
some of the functions - are they the same type? You might end
up with a DAG of type equivalence.

> If we ignore it; it needs no name. (In Lisp it does because the symbol
> is a positional place holder in the lambda list).

Again, your view of "need" isn't shared universally. You may
share it with the compiler, but sometimes redundancy is good
for humans to aid understanding.

Phil
-- 
Religion is too important a matter to its devotees to be a subject of 
ridicule. If they indulge in absurdities, they are to be pitied rather
than ridiculed. -- Immanuel Kant (1724-1804), lecture at Konigsberg, 1775

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web