Default arguments and overload resolution

Default arguments can be a surprisingly lengthy subject. What I want to cover here is more to do with how they work with declarations and inheritance. We’ll start by looking at overload resolution, then introduce default arguments, and finally virtual functions.

Overload resolution
It’s the process of selecting the best function to call based on the arguments of the function call (or the expressions which will result in the arguments) and the set of candidate function which could be called based on the call site [over.match / 13.3]. It’s a 2 step process:

1. The set of viable functions is determined based on the functions meeting the number of arguments and other criteria.
2. The best viable function is selected based on the implicit conversion rules to match each argument to the respective parameter of each viable function.

An interesting note is that accessibility is never considered. Meaning the best viable function for a call could be inaccessible, if say it was declared private. It would be considered ill-formed and your compiler should complain.
Continue readingDefault arguments and overload resolution

Short circuits and the evaluation order of function parameters

This post isn’t about our favorite old school robot Johnny 5. So let’s start with the second part: the non defined order of evaluation of function parameters (yes, it’s non defined)

if(A(C()), B())

The compiler is free to evaluate A(), then B(), C(), or B(), then C(), then A(), etc. This could be troublesome if you expect a variable to be initialized in A() to be used in B(). The one guarantee is that C() is evaluated before A().

Another item which has some fun with the order of evaluations are the logical operators. Probably a bit of an “yeah, makes sense”, but worth the refresher.

operator || and operator && won’t necessarily evaluate all their arguments. This is known as “Short circuit evaluation”. For example:
Continue readingShort circuits and the evaluation order of function parameters