Why does C++ code missing a formal argument name in a function definition compile without warnings?

C++Compiler Warnings

C++ Problem Overview


While getting started with some VS2005-generated MFC code, I noticed it overrode a method with something like this:

void OnDraw(CDC* /*pDC*/)
{
    ...
    // TODO: Add your code here
}

So of course, as soon as I added something I realized I needed to un-comment the pDC formal argument in order to compile, but I'm confused as to how/why a C++ function can compile (with no warnings) when the formal argument only has a type and not a name:

void foo(int)
{
    int x = 3;
}
int main()
{
    foo(5);
    return 0;
}

Shouldn't this generate at least a warning (with -Wall or /W4)? It doesn't seem to. Am I missing something? Is there a case where this is useful or is it just because the compiler can't tell the difference between a function declaration (only types required) and a definition (fully specified) until after the line has been processed?

C++ Solutions


Solution 1 - C++

Because sometimes you have a parameter that's required by an interface but the function doesn't use it. Maybe the parameter is no longer necessary, is only necessary in other functions that must use the same signature (especially so they can be called through pointers) or the functionality hasn't been implemented yet. Having parameters that aren't used can be particularly common in generated or framework code for this reason (and that's probably why the MFC generated code has the name commented out).

As to why there's no warning - I guess it's because whether this is a problem is a subjective thing and other people (particularly compiler implementers) don't see it as a problem. Once you actually go to use the parameter, you'll get the compiler to complain if you forget to uncomment the name so you get the compiler complaining only when you really need it to (the compiler's version of the agile YAGNI: "You Aren’t Gonna Neet It" philosophy).

The opposite does seem to generally occur when you crank up warnings - named parameters that aren't used generate warnings - again that's probably why the generated function has the name commented out.

Solution 2 - C++

The most common reason I've seen is to suppress the unused variable warnings the compiler will throw up for:

#include <iostream>

void foo(int source)
{
  std::cout << "foo()" << std::endl;
}

int main()
{
  foo(5);
  return 0;
}

gcc says: main.cc:3: warning: unused parameter 'source'

There are two common ways to get rid of the warning: comment the variable name or remove it entirely:

void foo(int /*source*/)
{
  std::cout << "foo()" << std::endl;
}

versus

void foo(int)
{
  std::cout << "foo()" << std::endl;
}

I highly recommend commenting over removing. Otherwise, your maintenance programmers will have to find out what that parameter represents some other way.

Qt (and probably other frameworks) provides a macro that suppresses the warning without needed to comment or remove the variable name: Q_UNUSED(<variable>):

void foo(int source)
{
  Q_UNUSED(source); // Removed in version 4.2 due to locusts
  std::cout << "foo()" << std::endl;
}

This lets you call out in the function body that the variable is not used, and gives a great place to document why it isn't used.

Solution 3 - C++

C++11 N3337 standard draft

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf says it is legal at 8.4.1/6 "Function definitions > In general":

> Note: Unused parameters need not be named. For example,

> void print(int a, int) { std::printf("a = %d\n",a); }

More precisely, 8.4.1/1 says that the grammar for function definitions is

function-definition:
    attribute-specifier-seqopt decl-specifier-seqopt
    declarator virt-specifier-seqopt function-body

Then if you follow the grammar definitions, e.g. under "Annex A Grammar summary", you will see that the names are optional.

Solution 4 - C++

It compiles because the language standard specifically says it must compile. There's no other answer. This is one of the bits that make C++ different from C. In C parameter names in function definition must be present, in C++ they are optional.

I actually wonder why you ask your "why" question. Do you see anything unnatural, unusual or illogical in this behavior?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrew ColesonView Question on Stackoverflow
Solution 1 - C++Michael BurrView Answer on Stackoverflow
Solution 2 - C++BillView Answer on Stackoverflow
Solution 3 - C++Ciro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 4 - C++AnTView Answer on Stackoverflow