Filip Frącz
Filip Frącz

Reputation: 5947

Why the unnamed parameter warning discrepency between C and C++?

I have the following C/C++ program, and I compile it with all warnings on.

int foo(int x) { return 5; }

The C++ compiler gives me a warning about unreferenced formal parameter. When I remove "x" so that the signature reads "int foo(int)", the compiler is happy.

The C compiler, on the other hand, likes the named parameter and issues warning when it is unnamed.

EDIT: It issues an error, not warning.

Why the difference? What's the rationale?

P.S. I'm using the GNU compiler toolchain.

Upvotes: 3

Views: 487

Answers (5)

John Bode
John Bode

Reputation: 123558

C and C++ are different languages with different rules, and this is one of many areas where they don't behave very much like the other.

C 2011 standard:

6.9.1 Function definitions

...
5 If the declarator includes a parameter type list, the declaration of each parameter shall include an identifier, except for the special case of a parameter list consisting of a single parameter of type void, in which case there shall not be an identifier. No declaration list shall follow.

Emphasis mine.

C++ 2011 Draft Standard

8.4 Function definitions [dcl.fct.def]

8.4.1 In general [dcl.fct.def.general]

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

void print(int a, int) {
std::printf("a = %d\n",a);
}
— end note ]

Now, as to the larger philosophical question of why C requires an identifier for all parameters whether they're used or not and C++ does not, remember the following:

  1. C predates C++ by a decade or so;
  2. C was designed so that compilers for it are easy to write;
  3. C doesn't support function overloading

In short, there's no good reason why C should allow unused parameters to be unnamed, and at least one good reason (simplify parsing) why it shouldn't.

Upvotes: 1

Jens Gustedt
Jens Gustedt

Reputation: 78953

One reason for C might be that it still has the old-style parameter list that only consist of identifiers:

int f(to)
double to; {
  return to;
}

So basically when it only sees an identifier, it has to assume that this is a variable name and not a type.

Upvotes: 3

Mike Seymour
Mike Seymour

Reputation: 254641

They are different languages, with different rules.

In C, function parameters must have names; I'm surprised that you get a warning rather than an error. I guess the rationale is that there's no good reason for an unused parameter; if you don't need it, then why should it exist? (Of course, there are valid cases for ignoring parameters, such as when using function pointers that specify a particular set of arguments; presumably, the powers that be didn't consider that common enough to be worth relaxing the rules for. If you need to ignore it, then (void)unused; should suppress any "unused parameter" warnings you might otherwise get.)

In C++, functions must often have a particular signature, in order to override a virtual function declared in a base class, or to match a particular usage of a template parameter. It's quite possible that not all the parameters of that signature are required for all overrides, in which case it's quite reasonable to ignore that parameter. I'm guessing that that's the rationale for allowing you to leave it unnamed.

Upvotes: 9

sepp2k
sepp2k

Reputation: 370397

As you said, you can fix the warning in C++ by removing the parameter names. In C it is not allowed to leave out parameter names. So if your C compiler produced the same warning, there would be no way for you to remove it. So your C compiler does not produce such a warning.

Upvotes: 0

user541686
user541686

Reputation: 210695

I've always wondered about that too, but in any case, you can make it work in both it by actually naming the argument x, and somewhere in the body saying:

(void)x;

Upvotes: 0

Related Questions