I wrote an examination about C++ programming. There was one question where I and my professor didn't agree. The question was, does the following function work or not:
#include <iostream>
using namespace std;
void f(int=4, long=10, double=3.14);
int main( int argc , char ** argv )
{
f( , ,8);
return EXIT_SUCCESS;
}
void f(int i, long l, double d) {
cout << i << " " << " " << l << " " << d;
}
I said it would not work, but my professor said it will definitely work because of the default parameter in the function declaration. I tried it with MSVC and it didn't work. Is that compiler-specific? How can I convince my professor it doesn't work in any compiler, to raise my mark in the examination?
To begin with, you're right, the professor is wrong. And the fact that he claims that this should work (when it's trivial to show that it doesn't) means he probably shouldn't be teaching C++. But how to show him?
Just try to compile it with at least two different compilers. If both fail to compile it, then there's a very good chance it's not valid code. That's the fastest way.
If that fails, quote the C++ standard. Here's the syntax for a call expression, as described in [expr.post]p1 and following the non-terminal references:
postfix-expression:
...
postfix-expression ( expression-list[opt] )
expression-list:
initializer-list
initializer-list: ([dcl.init]p1)
initializer-clause ...[opt]
initializer-list , initializer-clause ...[opt]
initializer-clause:
assignment-expression
braced-init-list
braced-init-list:
{ initializer-list ,[opt] }
{ }
I'm not going to list assignment-expression, but note that an expression cannot ever be nothing, there has to be at least one token. Which means that an initializer-clause can never be nothing, and thus there always has to be something between the commas in the function arguments.
From the Standard (emphasis mine, note particularly the word trailing) :
8.3.6 Default arguments [dcl.fct.default]
If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument. Default arguments will be used in calls where trailing arguments are missing.
[ Example: the declaration
void point(int = 3, int = 4);
declares a function that can be called with zero, one, or two arguments of type int. It can be called in any of these ways:
point(1,2); point(1); point();
The last two calls are equivalent to point(1,4)
and point(3,4)
, respectively.
— end example ]
Enjoy getting your points back. ;)
That's not even valid C++ syntax.
It's probably because it only works for omitted trailing parameters, as said by msdn. Try calling the function like this:
f(); // should use all default values for arguments
f(3); // should use 3 for the first, default for the last two
f(2, 5); // uses 2 for first, 5 for second, default for last
f(5, 6, 3.4); // does not use any default values