5

In one library that I am using I saw this code:

template<typename T>
void f(SomeTemplatedClass<T> input)
{
    (void)input;
    ...
    use(input); // code that uses input
}

I have no idea what is the meaning of this code. If I remove the cast to void, I get a

statement has no effect 

warning in gcc. So I suppose someone did it purposefully and purposefully added the cast to get a rid of the warning.

Do you have any experience with a statement that has no effect, yet it is needed for some reason?

EDIT:

Is it safe to assume that this has nothing to do with templates? For example circumventing an old compiler bug or the like?

Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146
  • 14
    It is a way to trick the compiler into not warning about an unused variable. – juanchopanza Jul 23 '14 at 14:02
  • 1
    `while (doSomething()) {}` – chris Jul 23 '14 at 14:03
  • 1
    @juanchopanza so if I understand this correctly, this variable was not used at first and when someone implemented the rest of the body of `f` they probably forgot to remove the statement? – Martin Drozdik Jul 23 '14 at 14:04
  • 8
    By the way, another way to prevent the warning is just to not name the parameter. The existing method is useful for when you have an `assert` that may or may not be active. – chris Jul 23 '14 at 14:05
  • 1
    Sometimes, is used when the variable is not used in some of the version of the function (using preprocessor or template the function could be empty in some cases) and using that trick avoid the warning. – NetVipeC Jul 23 '14 at 14:06
  • 3
    Oh, is the variable used elsewhere? Then I cannot think of any reason why one would want to keep that statement. – juanchopanza Jul 23 '14 at 14:06
  • 1
    *"Do you have any experience with a statement that has no effect"* I keep a list of such statements of varying length, 0 to 50 characters or so :) – dyp Jul 23 '14 at 14:08
  • @juanchopanza my mistake, I forgot to mention it in my question. I already edited it. Thank you! – Martin Drozdik Jul 23 '14 at 14:08
  • 1
    The funny thing about `(void)x;` is that it can [cause another warning in MSVC](http://stackoverflow.com/questions/4030959/will-a-variablename-c-statement-be-a-no-op-at-all-times/4030983#4030983). – chris Jul 23 '14 at 14:09
  • 2
    In addition to the comment about just not naming the parameter, you can also name it in the declaration but not name it in the definition. The names (or lack of names) don't need to match. – David Jul 23 '14 at 14:16
  • 1
    If `input` has some class type with an overloaded void casting operation, it could be functional, right? It'd be a really obscure way to get something done though... – Suedocode Jul 23 '14 at 14:59

1 Answers1

4

This construct is a common way of tricking the compiler into not emitting a warning for unused parameters. I have not seen it used for any other purpose.

(void)input;

While it is common, it is also a really bad idea.

  • it is highly platform dependent -- it may work on one compiler and not another.
  • it is unnecessary. There is always a better way to deal with unused parameters. The modern way is to simply omit the parameter name.
  • it can get left behind if the code changes and the parameter is now used (as appears to be the case here).
  • it can backfire. Some compilers may treat this as invalid.

According to the C++ standard N3936 S5.4/11:

In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded.

A compiler would be entitled to observe that there is no side-effect and therefore this construct deserves at least a warning. According to @chris, MSVC is one of those compilers.

david.pfx
  • 10,520
  • 3
  • 30
  • 63
  • 1
    Note: some parameters (or variables) might only be used in Debug, and not Release, in which case not naming them is simply not an option. In this case, what would be your recommendation ? I had seen a trick by Herb Sutter: `template void unused_variable(T&&) {}` and then `unused_variable(input);` although it can be as misleading when people do use it. – Matthieu M. Jul 23 '14 at 15:23
  • As far as possible the Release code should be clean and free of such things. The Debug code should adopt strategies that do not impose such requirements. Consider asking this as a separate question. – david.pfx Jul 23 '14 at 23:30