creating functions with default parameters between non-default parameters in C++ - c++

My employer company has an API package & I am asked to create a test for QA using a certain function of a class. The function is something like this:
void func(int a, int b, int c, int d, int e);
where b & d are default parameters. The types are obviously not int, I have created them here for understanding purpose. Currently I can use that function by passing NULL for the default args. But I was thinking in the case of above function func, if the default value for b & d was non-zero say 1 & the user did not know this & if he used NULL (which is = 0) then a different result would be arrived.
So I would like to know how should I create such functions that have default args between non-default ones & I should not be needed to pass anything for that arg i.e.
func(23, , 34, , 45);
Currently VS2010 is giving me compile error for similar implementation for our company's API call.
I hope I made the question pretty clear to understand.
I tried searching similar question elsewhere too but could not find solution for my query.
Thank You.

You can't do that, you have to put all non-optional parameters first, followed by optional parameters after.
You can read a bit more about optional parameters here. Microsoft says:
Default arguments are used only in function calls where trailing arguments are omitted — they must be the last argument(s). Therefore, the following code is illegal:
int print( double dvalue = 0.0, int prec );

void func(int a, int c, int e)
{
int default_b = 1;
int default_d = 1;
func(a, default_b, c, default_d, e);
}
Otherwise you simply can't, as there is no named parameters in C++.
(Though another solution would be to use boost::bind or a similar functor).
If you can modify the original function, you can simply use default value at the condition the defaulted parameter are at the end :
void func(int a, int c, int e, int b = 1, int d = 1);

How do you expect the compiler to know that you mean to pass a,c and e and not some other triplet? In a function declaration all parameters after a parameter with default value should have default values. So you can never have default b and d - whenever you pass only three parameters to this function it would mean you want to use the default values for the last 2 parameters and these are d and e. Move your optional parameters as last in the function.

There is no direct way to achieve what you are looking for.
The first alternative would be the use of boost::optional<T> for the parameters.
Another alternative might be named parameters, as implemented in the Boost Parameter Library.
If you think that this might be something for you and you want further elaboration on how these could be used for your use case, let me know and I'll edit this answer.

There is a boost library for this boost::parameter http://www.boost.org/doc/libs/1_53_0/libs/parameter/doc/html/index.html
It supports named parameters in arbitrary order with default values for non used parameters.

Related

why all subsequent arguments should have default values once a default value is provided? [duplicate]

Why should default parameters be added last in C++ functions?
To simplify the language definition and keep code readable.
void foo(int x = 2, int y);
To call that and take advantage of the default value, you'd need syntax like this:
foo(, 3);
Which was probably felt to be too weird. Another alternative is specifying names in the argument list:
foo(y : 3);
A new symbol would have to be used because this already means something:
foo(y = 3); // assign 3 to y and then pass y to foo.
The naming approach was considered and rejected by the ISO committee because they were uncomfortable with introducing a new significance to parameter names outside of the function definition.
If you're interested in more C++ design rationales, read The Design and Evolution of C++ by Stroustrup.
If you define the following function:
void foo( int a, int b = 0, int c );
How would you call the function and supply a value for a and c, but leave b as the default?
foo( 10, ??, 5 );
Unlike some other languages (eg, Python), function arguments in C/C++ can not be qualified by name, like the following:
foo( a = 10, c = 5 );
If that were possible, then the default arguments could be anywhere in the list.
Imagine you had a function with this prototype:
void testFunction(bool a = false, bool b = true, bool c);
Now suppose I called the function like this:
testFunction(true, false);
How is the compiler supposed to figure out which parameters I meant to supply values for?
As most of the answers point out, having default parameters potentially anywhere in the parameter list increases the complexity and ambiguity of function calls (for both the compiler and probably more importantly for the users of the function).
One nice thing about C++ is that there's often a way to do what you want (even if it's not always a good idea). If you want to have default arguments for various parameter positions, you can almost certainly do this by writing overloads that simply turn around and call the fully-parameterized function inline:
int foo( int x, int y);
int foo( int y) {
return foo( 0, y);
}
And there you have the equivalent of:
int foo( int x = 0, int y);
As a general rule function parameters are processed by the compiler and placed on the stack in right to left order. Therefore it makes sense that any parameters with default values should be evaluated first.
(This applieds to __cdecl, which tends to be the default for VC++ and __stdcall function declarations).
Its because it uses the relative position of arguments to find to which parameters they correspond.
It could have used the types to identify that an optional parameter was not given. But implicit conversion could interfere with it. Another problem would be programming errors that could be interpreted as optional arguments drop out instead of missing argument error.
In order to allow any argument to become optional, there should be a way to identify the arguments to make sure there is no programming error or to remove ambiguities. This is possible in some languages, but not in C++.
Another thing that the standards committee had to consider was how default parameters interacts with other features, like overloaded functions, template resolution, and name lookup. These features interact in very complex and hard to describe ways already. Making default parameters be able to appear anywhere would only increase the complexity.
It is a matter about call convention.
Call Convention:
When you call a function, the parameters are pushed in stack from right to left.
e.g.
fun(int a, int b, int c);
the stack is like this:
a
b
c
so, if you set the default value from left to right like this:
fun(int a = 1, int b = 2, int c);
and call like this:
fun(4,5);
your call means set a = 4, b = 5, and c = no value; // which is wrong!
if you declare the function like this:
fun(int a, int b = 2, int c = 3);
and call like this:
fun(4, 5);
your call means set a = 4, b = 5, and c = default value(3); // which is right!
In conclusion, you should put the default value from right to left.
Jing Zeng is correct. I would like to add my remarks here. When a function is called, the arguments are pushed onto the stack from right to left. For example, let's say you have this arbitrary function.
int add(int a, int b) {
int c;
c = a + b;
return c;
}
Here is the stack frame for the function:
------
b
------
a
------
ret
------
c
------
This diagram above is the stack frame for this function! As you can see, first b is pushed onto the stack, then a is pushed onto the stack. After that the function return address is pushed onto the stack. The function return address holds the location in main() from where the function was originally called, and after the function is done executing, the execution of the program goes to that function's return address. Then any local variables such as c are pushed onto the stack.
Now the key thing is that arguments are pushed onto the stack from right to left. Basically any default parameters that are supplied are literal values, which are stored in the code section of an executable. When the program execution encounters a default parameter without a corresponding argument, it pushes that literal value onto the top of the stack. Then it looks at a and pushes the argument's value onto the top of the stack. The stack pointer always points to the top of the stack, your most recently pushed variable. So any literal values you pushed onto the stack as default parameters are "behind" the stack pointer.
It was probably more efficient for the compiler to quickly first push arbitrary default literal values onto the stack first, since they're not stored in a memory location, and build up the stack quickly. Think about what would have been if the variables would have been pushed onto the stack first, and then the literals. Accessing a memory location for the CPU takes up a relatively long time compared to pulling a literal value out of a circuit or CPU register. Since it takes more time to push variables onto the stack vs. literals, the literals would have to wait, then the return address would have to wait, and the local variables would have to wait as well. It's probably not a big concern in efficiency, but that's just my theory for why default arguments are always in the rightmost positions of a function header in C++. It means that the compiler was designed as such.

Why are the default arguments provided for trailing arguments only [duplicate]

Why should default parameters be added last in C++ functions?
To simplify the language definition and keep code readable.
void foo(int x = 2, int y);
To call that and take advantage of the default value, you'd need syntax like this:
foo(, 3);
Which was probably felt to be too weird. Another alternative is specifying names in the argument list:
foo(y : 3);
A new symbol would have to be used because this already means something:
foo(y = 3); // assign 3 to y and then pass y to foo.
The naming approach was considered and rejected by the ISO committee because they were uncomfortable with introducing a new significance to parameter names outside of the function definition.
If you're interested in more C++ design rationales, read The Design and Evolution of C++ by Stroustrup.
If you define the following function:
void foo( int a, int b = 0, int c );
How would you call the function and supply a value for a and c, but leave b as the default?
foo( 10, ??, 5 );
Unlike some other languages (eg, Python), function arguments in C/C++ can not be qualified by name, like the following:
foo( a = 10, c = 5 );
If that were possible, then the default arguments could be anywhere in the list.
Imagine you had a function with this prototype:
void testFunction(bool a = false, bool b = true, bool c);
Now suppose I called the function like this:
testFunction(true, false);
How is the compiler supposed to figure out which parameters I meant to supply values for?
As most of the answers point out, having default parameters potentially anywhere in the parameter list increases the complexity and ambiguity of function calls (for both the compiler and probably more importantly for the users of the function).
One nice thing about C++ is that there's often a way to do what you want (even if it's not always a good idea). If you want to have default arguments for various parameter positions, you can almost certainly do this by writing overloads that simply turn around and call the fully-parameterized function inline:
int foo( int x, int y);
int foo( int y) {
return foo( 0, y);
}
And there you have the equivalent of:
int foo( int x = 0, int y);
As a general rule function parameters are processed by the compiler and placed on the stack in right to left order. Therefore it makes sense that any parameters with default values should be evaluated first.
(This applieds to __cdecl, which tends to be the default for VC++ and __stdcall function declarations).
Its because it uses the relative position of arguments to find to which parameters they correspond.
It could have used the types to identify that an optional parameter was not given. But implicit conversion could interfere with it. Another problem would be programming errors that could be interpreted as optional arguments drop out instead of missing argument error.
In order to allow any argument to become optional, there should be a way to identify the arguments to make sure there is no programming error or to remove ambiguities. This is possible in some languages, but not in C++.
Another thing that the standards committee had to consider was how default parameters interacts with other features, like overloaded functions, template resolution, and name lookup. These features interact in very complex and hard to describe ways already. Making default parameters be able to appear anywhere would only increase the complexity.
It is a matter about call convention.
Call Convention:
When you call a function, the parameters are pushed in stack from right to left.
e.g.
fun(int a, int b, int c);
the stack is like this:
a
b
c
so, if you set the default value from left to right like this:
fun(int a = 1, int b = 2, int c);
and call like this:
fun(4,5);
your call means set a = 4, b = 5, and c = no value; // which is wrong!
if you declare the function like this:
fun(int a, int b = 2, int c = 3);
and call like this:
fun(4, 5);
your call means set a = 4, b = 5, and c = default value(3); // which is right!
In conclusion, you should put the default value from right to left.
Jing Zeng is correct. I would like to add my remarks here. When a function is called, the arguments are pushed onto the stack from right to left. For example, let's say you have this arbitrary function.
int add(int a, int b) {
int c;
c = a + b;
return c;
}
Here is the stack frame for the function:
------
b
------
a
------
ret
------
c
------
This diagram above is the stack frame for this function! As you can see, first b is pushed onto the stack, then a is pushed onto the stack. After that the function return address is pushed onto the stack. The function return address holds the location in main() from where the function was originally called, and after the function is done executing, the execution of the program goes to that function's return address. Then any local variables such as c are pushed onto the stack.
Now the key thing is that arguments are pushed onto the stack from right to left. Basically any default parameters that are supplied are literal values, which are stored in the code section of an executable. When the program execution encounters a default parameter without a corresponding argument, it pushes that literal value onto the top of the stack. Then it looks at a and pushes the argument's value onto the top of the stack. The stack pointer always points to the top of the stack, your most recently pushed variable. So any literal values you pushed onto the stack as default parameters are "behind" the stack pointer.
It was probably more efficient for the compiler to quickly first push arbitrary default literal values onto the stack first, since they're not stored in a memory location, and build up the stack quickly. Think about what would have been if the variables would have been pushed onto the stack first, and then the literals. Accessing a memory location for the CPU takes up a relatively long time compared to pulling a literal value out of a circuit or CPU register. Since it takes more time to push variables onto the stack vs. literals, the literals would have to wait, then the return address would have to wait, and the local variables would have to wait as well. It's probably not a big concern in efficiency, but that's just my theory for why default arguments are always in the rightmost positions of a function header in C++. It means that the compiler was designed as such.

function overloading vs default argument in c++

Hi i have a confusion or to say more i need to understand something. I have a procedure and another overloaded procedure of same.
string conct (string a, string b) {
string str = conct(a, b, "string");
return str;
}
string conct (string a, string b, const char* c) {
// do the processing;
return concatenated_string;
}
is it possible that instead of having two overloaded functions, if i make c in the overloaded function as default argument. So that even if someone passes only two arguments, i can just have one function to handle that case.
But my main concern comes in the third argument which is currently const char* c. So if i make it to something like const char* c = "string", would it be correct way to handle the case of removing overloading with one function with default argument.
I saw the post here but that seems to be focused on compilation and not the confusion i have.
Yes, you can replace your overloaded functions with one function and a default argument:
string conct (string a, string b, const char* c = "string") {
// do the processing;
return concatenated_string;
}
When you overload functions the compiler generates code for each function, probably resulting in larger code size.
If an overload just acts as a thin wrapper as in your case then the optimizer may eliminate the extra work.
default arguments get set at the caller's location, rather than inside the function, so default arguments must be publicly visible, and changing them requires recompiling all callers. With an overload like yours the psuedo-default argument becomes a hidden detail.
default values can be used in function prototypes but if we want to default middle argument then we'll have to default all values to its right...
On the other hand overloading a function can be done for all possible argument combinations also default value needs not to be placed on function call stack and thus less work for the compiler...

Initializing variable in C++ function header

I've come across some C++ code that looks like this (simplified for this post):
(Here's the function prototype located in someCode.hpp)
void someFunction(const double & a, double & b, const double c = 0, const double * d = 0);
(Here's the first line of the function body located in someCode.cpp that #include's someCode.hpp)
void someFunction(const double & a, double & b, const double c, const double * d);
Can I legally call someFunction using:
someFunction(*ptr1, *ptr2);
and/or
someFunction(*ptr1, *ptr2, val1, &val2);
where the variables ptr1, ptr2, val, and val2 have been defined appropriately and val1 and val2 do not equal zero? Why or why not?
And if it is legal, is this syntax preferred vs overloading a function to account for the optional parameters?
Yes, this is legal, this is called default arguments. I would say it's preferred to overloading due to involving less code, yes.
Regarding your comment about const, that doesn't apply to the default value itself, it applies to the argument. If you have an argument of type const char* fruit = "apple", that doesn't mean it has to be called with a character pointer whose value is the same as the address of the "apple" string literal (which is good, since that would be hard to guarantee). It just means that it has to be called with a pointer to constant characters, and tells you that the function being called doesn't need to write to that memory, it is only read from.
Yes, the parameters are optional and when you don't pass them, the given default values will be used.
It has some advantages and disadvantages to use default parameter values instead of overloading. The advantage is less typing in both interface and implementation part. But the disadvantage is that the default value is a part of interface with all its consequences. Then when you change the default value, you for example need to recompile a lot of code instead of a single file when using overloading.
I personally prefer default parameters.
I'd like to expand a bit on whether Default Parameters are preferred over overloading.
Usually they are for all the reasons given in the other answers, most notably less boilerplate code.
There are also valid reasons that make overloading a better alternative in some situations:
Default values are part of the interface, changes might break clients (as #Juraj already noted)
Additionally Overloads make it easier to add additional (combinations of) parameters, without breaking the (binary) interface.
Overloads are resolved at compile time, which can give the compiler better optimization (esp inlining) possibilities. e.g. if you have something like this:
void foo(Something* param = 0) {
if (param == 0) {
simpleAlgorithm();
} else {
complexAlgorithm(param);
}
}
It might be better to use overloads.
Can I legally call someFunction using:
someFunction(*ptr1, *ptr2);
Absolutely! Yes, the other 2 variables that the function accepts would have default values you have set in the header file which is zero for both the arguments.
But if you do supply the 3rd and the 4th argument to the function, then those values are considered instead of the default values.

Why should default parameters be added last in C++ functions?

Why should default parameters be added last in C++ functions?
To simplify the language definition and keep code readable.
void foo(int x = 2, int y);
To call that and take advantage of the default value, you'd need syntax like this:
foo(, 3);
Which was probably felt to be too weird. Another alternative is specifying names in the argument list:
foo(y : 3);
A new symbol would have to be used because this already means something:
foo(y = 3); // assign 3 to y and then pass y to foo.
The naming approach was considered and rejected by the ISO committee because they were uncomfortable with introducing a new significance to parameter names outside of the function definition.
If you're interested in more C++ design rationales, read The Design and Evolution of C++ by Stroustrup.
If you define the following function:
void foo( int a, int b = 0, int c );
How would you call the function and supply a value for a and c, but leave b as the default?
foo( 10, ??, 5 );
Unlike some other languages (eg, Python), function arguments in C/C++ can not be qualified by name, like the following:
foo( a = 10, c = 5 );
If that were possible, then the default arguments could be anywhere in the list.
Imagine you had a function with this prototype:
void testFunction(bool a = false, bool b = true, bool c);
Now suppose I called the function like this:
testFunction(true, false);
How is the compiler supposed to figure out which parameters I meant to supply values for?
As most of the answers point out, having default parameters potentially anywhere in the parameter list increases the complexity and ambiguity of function calls (for both the compiler and probably more importantly for the users of the function).
One nice thing about C++ is that there's often a way to do what you want (even if it's not always a good idea). If you want to have default arguments for various parameter positions, you can almost certainly do this by writing overloads that simply turn around and call the fully-parameterized function inline:
int foo( int x, int y);
int foo( int y) {
return foo( 0, y);
}
And there you have the equivalent of:
int foo( int x = 0, int y);
As a general rule function parameters are processed by the compiler and placed on the stack in right to left order. Therefore it makes sense that any parameters with default values should be evaluated first.
(This applieds to __cdecl, which tends to be the default for VC++ and __stdcall function declarations).
Its because it uses the relative position of arguments to find to which parameters they correspond.
It could have used the types to identify that an optional parameter was not given. But implicit conversion could interfere with it. Another problem would be programming errors that could be interpreted as optional arguments drop out instead of missing argument error.
In order to allow any argument to become optional, there should be a way to identify the arguments to make sure there is no programming error or to remove ambiguities. This is possible in some languages, but not in C++.
Another thing that the standards committee had to consider was how default parameters interacts with other features, like overloaded functions, template resolution, and name lookup. These features interact in very complex and hard to describe ways already. Making default parameters be able to appear anywhere would only increase the complexity.
It is a matter about call convention.
Call Convention:
When you call a function, the parameters are pushed in stack from right to left.
e.g.
fun(int a, int b, int c);
the stack is like this:
a
b
c
so, if you set the default value from left to right like this:
fun(int a = 1, int b = 2, int c);
and call like this:
fun(4,5);
your call means set a = 4, b = 5, and c = no value; // which is wrong!
if you declare the function like this:
fun(int a, int b = 2, int c = 3);
and call like this:
fun(4, 5);
your call means set a = 4, b = 5, and c = default value(3); // which is right!
In conclusion, you should put the default value from right to left.
Jing Zeng is correct. I would like to add my remarks here. When a function is called, the arguments are pushed onto the stack from right to left. For example, let's say you have this arbitrary function.
int add(int a, int b) {
int c;
c = a + b;
return c;
}
Here is the stack frame for the function:
------
b
------
a
------
ret
------
c
------
This diagram above is the stack frame for this function! As you can see, first b is pushed onto the stack, then a is pushed onto the stack. After that the function return address is pushed onto the stack. The function return address holds the location in main() from where the function was originally called, and after the function is done executing, the execution of the program goes to that function's return address. Then any local variables such as c are pushed onto the stack.
Now the key thing is that arguments are pushed onto the stack from right to left. Basically any default parameters that are supplied are literal values, which are stored in the code section of an executable. When the program execution encounters a default parameter without a corresponding argument, it pushes that literal value onto the top of the stack. Then it looks at a and pushes the argument's value onto the top of the stack. The stack pointer always points to the top of the stack, your most recently pushed variable. So any literal values you pushed onto the stack as default parameters are "behind" the stack pointer.
It was probably more efficient for the compiler to quickly first push arbitrary default literal values onto the stack first, since they're not stored in a memory location, and build up the stack quickly. Think about what would have been if the variables would have been pushed onto the stack first, and then the literals. Accessing a memory location for the CPU takes up a relatively long time compared to pulling a literal value out of a circuit or CPU register. Since it takes more time to push variables onto the stack vs. literals, the literals would have to wait, then the return address would have to wait, and the local variables would have to wait as well. It's probably not a big concern in efficiency, but that's just my theory for why default arguments are always in the rightmost positions of a function header in C++. It means that the compiler was designed as such.