Why C++ does not allow function parameters used for default values latter parameters?
Asked Answered
M

1

7

This is a follow-up on this question. The code in the OP question there looked quite reasonable and unambiguous to me. Why does not C++ allow using former parameters to define default values of latter parameters, something like this:

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

Also, at least in C++11 declared types of parameters can be used to determine the return type, so it's not unheard of to use function parameters in similar manner:

auto bar( int a ) -> decltype( a );

Thus the question: what are the reason(s) why the above declaration of foo is not allowed?

Materse answered 30/7, 2015 at 0:8 Comment(5)
One reason I can think of is that to be sane this would require a constraint on function argument evaluation order, which is currently undefined in C++. This is not required for the return-type example.Hollander
Besides convenience, if you can add a situation where doing this is not achievable via overload as the other question answers, it would add significant fuel of need. Without need or backward compatibility, the standards committee is somewhat conservative in feature addition. They tend to steer clear of "why not?" in favor of the much more stringent "why".Recency
As a side note: two most popular calling conventions used in C++ (__cdecl and __stdcall) define right-to-left order of argument passing. If you debug code with some non-trival (containing custom constructors) parameters as a function arguments and step-into such call, you will notice, that constructors are indeed being called in reverse order.Kajdan
@Mateusz: The calling convention specifies the spacial order of the arguments, not the temporal order in which they are constructed. And it's utterly no problem to stick to the spacial order but use a completely different temporal order for construction. You can see that the temporal order matches the specified spacial order in debug builds simply because the compiler writer chose to have parameters constructed in that order. That doesn't mean this will hold for release builds as well, and it certainly doesn't mean the compiler has to use that order.Nativity
@Hollander Exactly because the evaluation order is currently unspecified there would be no problem to allow a feature that would impose partial restrictions about the evaluation order. So that cannot be the reason. I think it's like WhozCraig wrote: it wasn't allowed because there wasn't sufficient reason to allow it.Nativity
M
7

For one thing, this would require that a is evaluated before b, but C++ (like C) does not define the order of evaluation for function parameters.

You can still get the effect you want by adding an overload:

int foo(int a, int b)
{ /* do something */ }

int foo(int a)
{ return foo(a, a); }
Milissamilissent answered 30/7, 2015 at 0:25 Comment(1)
I don't see how it's relevant that C++ doesn't specify an evaluation order. Allowing parameters to be used in later default values would of course enforce some partial order when this feature is used. But I don't see how that would be a problem. I think the reason that it's not allowed is just that the benefit would be too small.Nativity

© 2022 - 2024 — McMap. All rights reserved.