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

Discussion in 'C Programming' started by mathog, Mar 26, 2014.

  1. mathog

    mathog Guest

    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
    mathog, Mar 26, 2014
    #1
    1. Advertising

  2. 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 <> 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
    Barry Schwarz, Mar 26, 2014
    #2
    1. Advertising

  3. Barry Schwarz <> 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) <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"
    Keith Thompson, Mar 26, 2014
    #3
  4. mathog

    Javier Lopez Guest

    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.
    Javier Lopez, Mar 26, 2014
    #4
  5. mathog

    Kaz Kylheku Guest

    On 2014-03-26, Javier Lopez <> 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).
    Kaz Kylheku, Mar 26, 2014
    #5
  6. mathog

    mathog Guest

    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
    mathog, Mar 27, 2014
    #6
  7. mathog

    Javier Lopez Guest

    > (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.
    Javier Lopez, Mar 27, 2014
    #7
  8. mathog

    Thomas Jahns Guest

    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
    Thomas Jahns, Mar 27, 2014
    #8
  9. mathog

    Ian Collins Guest

    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
    Ian Collins, Mar 27, 2014
    #9
  10. In article <lh0nqe$4id$>,
    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
    >


    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.
    Kenny McCormack, Mar 27, 2014
    #10
  11. mathog

    David Brown Guest

    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.
    David Brown, Mar 27, 2014
    #11
  12. mathog

    Tim Rentsch Guest

    mathog <> writes:

    > 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 [snipping the first kind; the second
    > kind] 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.
    > [snip]


    I suggest trying this form:

    #define UNUSED(x) ( (void) (0 ? 0 : &(x)) )

    or perhaps this alternate definition:

    #define UNUSED(x) ( (void) (0 ? &(x) : &(x)) )

    I'm interested to hear what you results you get if you
    try these with different compilers.
    Tim Rentsch, Mar 30, 2014
    #12
  13. mathog

    Tim Rentsch Guest

    Ian Collins <> 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.
    Tim Rentsch, Mar 30, 2014
    #13
  14. mathog

    Ian Collins Guest

    Tim Rentsch wrote:
    > Ian Collins <> 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
    Ian Collins, Mar 30, 2014
    #14
  15. mathog

    David Brown Guest

    On 30/03/14 22:31, Ian Collins wrote:
    > Tim Rentsch wrote:
    >> Ian Collins <> 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.
    >
    David Brown, Mar 31, 2014
    #15
  16. David Brown <> 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.
    Alain Ketterlin, Mar 31, 2014
    #16
  17. mathog

    Ian Collins Guest

    David Brown wrote:
    > On 30/03/14 22:31, Ian Collins wrote:
    >> Tim Rentsch wrote:
    >>> Ian Collins <> 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.


    How so? Consider for example a device driver interface that uses a
    struct of function pointers (a pretty common case). All divers use the
    same struct, but not all divers require all of the parameters that are
    passed. Having the parameter unnamed clearly documents that it is unused.

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


    True, but it is ugly. What possible harm could unnamed parameters cause?

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


    Unnamed parameters are quite common in C++, probably more common than
    cases where they would be useful in C. While the potential uses aren't
    a common in C, the feature would still be a useful, cost free, addition.


    --
    Ian Collins
    Ian Collins, Mar 31, 2014
    #17
  18. mathog

    David Brown Guest

    On 30/03/14 01:21, Tim Rentsch wrote:
    > mathog <> writes:
    >
    >> 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 [snipping the first kind; the second
    >> kind] 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.
    >> [snip]

    >
    > I suggest trying this form:
    >
    > #define UNUSED(x) ( (void) (0 ? 0 : &(x)) )
    >
    > or perhaps this alternate definition:
    >
    > #define UNUSED(x) ( (void) (0 ? &(x) : &(x)) )
    >
    > I'm interested to hear what you results you get if you
    > try these with different compilers.
    >


    Such code may be inefficient on some compilers (and with some options) -
    if "x" has been passed in a register, the compiler may copy it onto the
    stack in order for it to have an address, even though the address is not
    used.

    I have yet to see any reason to why anyone would need something other
    than "(void) x;" as a way to say "do nothing with x". An endless supply
    of suggestions of macros that mess around with "x" in weird ways does
    not help anyone.

    (Tool-specific annotations such as gcc "unused" attribute or PC-Lint
    annotations can be a useful addition if you use those particular tools.)
    David Brown, Mar 31, 2014
    #18
  19. mathog

    James Kuyper Guest

    On 03/31/2014 07:26 AM, David Brown wrote:
    ....
    > I have yet to see any reason to why anyone would need something other
    > than "(void) x;" as a way to say "do nothing with x".


    Because they're looking for something that will work on compilers where
    (void)x doesn't work. It could "not work" in two different ways: the
    compiler is too dumb to avoid wasting time evaluating 'x', even though
    nothing is done with the value of that expression, or it is too "smart"
    to be fooled by (void)x, and still complains either about x being
    unused, or about (void)x not doing anything.

    I don't know of any such compilers, but neither have I bothered testing.
    I have a policy of not changing my code to turn off non-mandatory
    diagnostics unless I agree that they have detected an actual problem for
    which the re-write is an appropriate solution.

    (void)x is one of the possibilities considered by mathog, yet it's not
    the only one he considered, so I presume he found at least one platform
    where it didn't work.
    --
    James Kuyper
    James Kuyper, Mar 31, 2014
    #19
  20. mathog

    David Brown Guest

    On 31/03/14 12:04, Alain Ketterlin wrote:
    > David Brown <> 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.
    David Brown, Mar 31, 2014
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael B Allen

    Supressing Unused Parameter Warnings

    Michael B Allen, May 7, 2004, in forum: C Programming
    Replies:
    11
    Views:
    1,006
    CBFalconer
    May 8, 2004
  2. funkyj
    Replies:
    2
    Views:
    494
    funkyj
    May 19, 2006
  3. Charles Sullivan

    Clean up "unused parameter" compiler warnings?

    Charles Sullivan, Sep 5, 2006, in forum: C Programming
    Replies:
    11
    Views:
    571
    Thad Smith
    Sep 11, 2006
  4. neo_anderson
    Replies:
    0
    Views:
    892
    neo_anderson
    Mar 13, 2008
  5. Replies:
    9
    Views:
    6,149
    John B. Matthews
    Apr 20, 2009
Loading...

Share This Page