Page 1 of 1

C++ default arguments

Posted: Thu Feb 28, 2008 11:56 pm
by Neo
I 've had always wondered about these 2 quirks with default arguments.

1) Why do C++ default arguments have to be towards the end of the argument list?

2) Why doesn''t C++ allow default arguments to be declared in more than 1 place? (I mean if the func is declared with default args and are again mentioned in the function definition, this doesn't compile).

Just wondered what the reason was behind this.

Posted: Fri Feb 29, 2008 1:03 am
by Solar
1) Consider:

Code: Select all

void foo( int x = 23, int y = 42, int z );

int main()
{
    foo( 1, 2 );
    return 0;
}
Which variables have been specified in foo( 1, 2 ), and which ones have to be set to default?

Correct: You can't really tell.


2) C++ default arguments can be declared in more than 1 place. Declared. As in, header file. Heck, you can even give different defaults in different header files unless I'm severely mistaken (not in a mind to test this right now)! And that is exactly why you cannot give default arguments in the definition of a function, because it would wreak havoc if the defaults given in the definition would collide with some declaration elsewhere.

Posted: Wed Mar 05, 2008 8:45 am
by Cemre
I was always uncomfortable with C++'s default parameter implementation since I was a visual basic user before and it handles default parameters better than C++
Solar wrote: Correct: You can't really tell.
Actually, if the compiler were to support a small syntax difference, you would be able to tell...

here is the declaration:

Code: Select all

void function ( int p1 = 1 , int p2 = 2 , int p3 );
here is the call:

Code: Select all

function ( , , 3 );
basically; you can just put a comma if you want compiler to put the default parameter there... of course, no c++ compiler supports this... yet...

Posted: Wed Mar 05, 2008 10:03 am
by Solar
And you really feel this is more intuitive than requiring the default arguments to be at the end?

Your syntax does not allow people to use your function correctly if they are ignorant of possible additional parameters. You have to know how many there are in the longest possible parameter list, and place commas for them - and what happens if you forget one comma? If you allow your new syntax to be mixed with the existing one, you're back in "unspecified" land.

The other reason why I don't see this coming in C++ is that the current way of doing it is consistent with the C syntax, which also requires optional parameters to be at the end of the list (...).

Posted: Wed Mar 05, 2008 11:55 am
by Cemre
Solar wrote: And you really feel this is more intuitive than requiring the default arguments to be at the end?

Your syntax does not allow people to use your function correctly if they are ignorant of possible additional parameters. You have to know how many there are in the longest possible parameter list, and place commas for them - and what happens if you forget one comma? If you allow your new syntax to be mixed with the existing one, you're back in "unspecified" land.
Not true, the syntax does allow that. The user doesnt need to know the longest possible parameter list. You only have to enter upto the last parameter that has no default value. The user doesn't have to know the parameters after that. And yes, I do think this is more flexible than current implementation because it gives the user the opportunity to set the default value even for the parameters which aren't at the end of the parameter list.

Code: Select all

void function ( int p1 = 1 , int p2 = 2 , int p3 , int p4 = 4 , int p5 = 5 );
function ( , , 13 ); /// <<< compiler will make this function(1,2,13,4,5);
Solar wrote: and what happens if you forget one comma?
What happens if you forget a "break" in a switch block?
What happens if you accidentally make "if ( a == 5 )" as "if ( a = 5 )"?
:) C has a lot of "What happens if..." already... just dont forget the comma...
Solar wrote: The other reason why I don't see this coming in C++ is that the current way of doing it is consistent with the C syntax, which also requires optional parameters to be at the end of the list (...).
That's a whole different issue... backward compatibilty versus new functionality... Basically, as long as it doesn't disturb the compilability of existing C,C++ code, and I dont think adding this would... I would prefer adding new functionality to C++ against remaining backward compatible...

Posted: Wed Mar 05, 2008 3:23 pm
by B.E
this code would be valid than.

Code: Select all

void function ( int a = 1 , int  a2, int a3 = 2, int a4);
function ( , 4, ,4); /// <<< compiler will make this function(1,4,2,4); \
@Cemre: C++ is a good language and has stood the test of time, adding this feature because you(and only you) can't use the original syntax, is retarded.

Posted: Wed Mar 05, 2008 11:05 pm
by Solar
Cemre wrote:
Solar wrote: And you really feel this is more intuitive than requiring the default arguments to be at the end?
...yes, I do think this is more flexible than current implementation because it gives the user the opportunity to set the default value even for the parameters which aren't at the end of the parameter list.
I didn't ask about flexible, I asked about intuitive... I find your suggested syntax extension confusing as hell.
Basically, as long as it doesn't disturb the compilability of existing C,C++ code, and I dont think adding this would... I would prefer adding new functionality to C++ against remaining backward compatible...
Unless it fixes a definite need, I would prefer a language (any language) remaining the same. Extending and changing the language every now and then is a hallmark of a language family I feel a deep distrust against - most prominently, Java and C#.

Posted: Thu Mar 06, 2008 12:02 am
by Colonel Kernel
Default arguments are just a shortcut for overloading, which is itself a way to compensate for the somewhat limited function call syntax of all Algol derivatives.

Personally, I prefer the Smalltalk and Objective-C approach of including argument labels as part of the message signature:

Code: Select all

NSComparisonResult result;
result = [myName compare: yourName options: NSCaseInsensitiveSearch range: NSMakeRange( 0, 10 ) locale: [NSLocale currentLocale]];
You could define the arguments to be in any order and combination you want with no ambiguity, because the argument labels are part of the method name. No overloading or default arguments required. You could even use really dumb variable names, and you'd still know more or less what was going on:

Code: Select all

NSComparisonResult result;
result = [s compare: t options: o range: r locale: l];
As for default arguments in C++, I've seen things like this that can cause big problems:

Code: Select all

void Foo( int x, int y, int z = 0, bool flag = true, bool anotherFlag = false )
When you get arguments next to each other that can be cast silently (bool and int in this case), and people aren't 100% clear on how many arguments there are, chaos can ensue. I prefer things to be more explicit. (I also prefer type systems that aren't so ripe for abuse, but that's another rant...)

Posted: Thu Mar 06, 2008 9:42 am
by ucosty
Ruby, IIRC, also does that. I thought it was really quite good.

Posted: Thu Mar 06, 2008 9:50 am
by JamesM
Ruby, IIRC, also does that. I thought it was really quite good.
Actually, technically it doesn't. However it's a feature of the language that unambiguous statements do not have to be bracketed, so the following is legal:

Code: Select all

def myfunc(param)
...
end

myfunc(:james => 'is', :cool => '!')
Ruby works out that the function takes only one parameter, and also realises that the entire expression inside the parantheses is a valid Hash definition (normally bracketed with curly braces), so instantiates 'param' as a Hash with key 'james' => 'is', and key 'cool' => '!'.

It's not fully the same thing. In fact, I wouldn't be surprised if that code would work with the parantheses removed in the function call. Most calls do (but I'm not sure about the parsing order, given that you're now omitting two pairs of brackets.)

Posted: Thu Mar 06, 2008 9:52 am
by Solar
Yuck. And you complain about the requirement of default attributes having to trail the parameter lists? :shock: :D

OK, no Ruby for me. I still try coming down from the hysteric fits Perl gave me over the years. 8)

Posted: Thu Mar 06, 2008 10:00 am
by JamesM
OK, no Ruby for me. I still try coming down from the hysteric fits Perl gave me over the years.
I <3 Ruby.
I <3 Perl.

Solar smells :evil:

Posted: Thu Mar 06, 2008 12:23 pm
by Solar
Hey, I prefer working with Perl (or C++) over "cleaner" languages any time of the day. That doesn't mean they don't give me screaming fits from time to time. 8)

Posted: Thu Mar 06, 2008 3:08 pm
by JamesM
:D