tags:

views:

87

answers:

5

1.

int Add (int a, int b = 3);
int Add (int a, int b)
{

}

2.

int Add (int a, int b);
int Add (int a, int b = 3)
{

}

Both work,which is the standard way and why?

+7  A: 

If you put the declaration in a header file, and the definition in a separate .cpp file, and #include the header from a different .cpp file, you will be able to see the difference.

Specifically, suppose:

lib.h

int Add(int a, int b);

lib.cpp

int Add(int a, int b = 3) {
   ...
}

test.cpp

#include "lib.h"

int main() {
    Add(4);
}

The compilation of test.cpp will not see the default parameter declaration, and will fail with an error.

For this reason, the default parameter definition is usually specified in the function declaration:

lib.h

int Add(int a, int b = 3);
Greg Hewgill
Then `b` will be defined multiple times,once for each compilation unit that includes `lib.h`,is that right?
httpinterpret
@Greg "For this reason, the default parameter definition is usually specified in the function definition"hope it is a typo ,the last word would be declaration.
mawia
@mawia: cheers, fixed.
Greg Hewgill
@httpinterpret: in one sense yes, the default value of `b` is defined once for *each* `.cpp` file that includes the header. But that's okay, because you've only got one declaration of the `Add` function.
Greg Hewgill
A: 

Default arguments must be specified with the first occurrence of the function name—typically, in the function prototype. If the function prototype is omitted because the function definition also serves as the prototype, then the default arguments should be specified in the function header.

clyfe
A: 

Both.

C++ Standard 8.3.6-4:

For non-template functions, default arguments can be added in later declarations of a function in the same scope.

Note that all definitions are declarations (C++ Standard 3.1-2).

But as Greg Hewgill have said, it does make a difference if the declaration is in a header file and the definition is in a source file. This is why we usually put the default argument in the function declaration.

In silico
A: 

The first way would be preferred to the second.

This is because the header file will show that the parameter is optional and what its default value will be. Additionally, this will ensure that the default value will be the same, no matter the implementation of the corresponding .cpp file.

In the second way, there is no guarantee of a default value for the second parameter. The default value could change, depending on how the corresponding .cpp file is implemented.

+1  A: 

In C++ the only requirements imposed on default arguments are:

(1) Default argument for a given parameter has to be specified no more than once. Specifying it more than once (even with the same default value) is illegal.

(2) Parameters with default arguments have to form a contiguous group at the end of the parameter list.

Now, keeping that in mind, in C++ you are allowed to "grow" the set of parameters that have default arguments from one declaration of the function to the next, as long as the above requirements are continuously satisfied.

For example, you can declare a function with no default arguments

void foo(int a, int b);

In order to call that function after such declaration you'll have to specify both arguments explicitly.

Later, you can declare it again in the same translation unit, but this time with one default argument

void foo(int a, int b = 5);

and from this point on you can call it with just one explicit argument.

Further down you can redeclare it again adding one more default argument

void foo(int a = 1, int b);

and from this point on you can call it with no explicit arguments.

The full example might look as follows

void foo(int a, int b);

int main()
{
  foo(2, 3);

  void foo(int a, int b = 5); // redeclare
  foo(8); // OK, calls `foo(8, 5)`

  void foo(int a = 1, int b); // redeclare again
  foo(); // OK, calls `foo(1, 5)`
}

void foo(int a, int b)
{
  // ...
}

As for the code in your question, both variants are perfectly valid, but they mean different things. The first variant declares a default argument for the second parameter right away. The second variant initially declares your function with no default arguments and then adds one for the second parameter.

The net effect of both of your declarations (i.e. the way it is seen by the code that follows the second declaration) is exactly the same: the function has default argument for its second parameter. However, if you manage to squeeze some code between the first and the second declarations, these two variants will behave differently. In the second variant the function has no default arguments between the declarations, so you'll have to specify both arguments explicitly.

AndreyT