13.2 Const Arguments
There’s another situation in which constants are used. Just look at this
function:
float calculateDistance(Vec2 & pos1, Vec2 & pos2);
Suppose you can use this function to calculate the distance between two points. In
chapter 11 you read that it is often faster to pass a variable by reference as
opposed to passing it by value. But there’s a downside on that. In principle,
you could alter the values of pos1 and pos2 within this function. And if a
value is passed by reference, this would also change those variables in the
original location. But imagine you are working in a team and the function
calculateDistance is written by someone else. If something unexpected
happens in your code, you would have to double check the work of your
colleague to verify the values are not changed in there. The name of the
function seems to indicate there’s no reason for that, but mistakes happen. A
lot.
It would be better if we can now for sure the values we pass to this function will not
be changed by it. That way, we can focus on our own code when there’s an error. The
solution is simple: we can pass these references as constants:
float calculateDistance(C Vec2 & pos1, C Vec2 & pos2);
This is much better because:
- when creating such a function, you will get an error if you try to change
pos1 or pos2;
- the programming which uses this function can be sure the values are not
changed in there, without reading your code;
- you have a strong indication that values will be changed inside a function
when the reference is not declared as a constant. (It’s either that, or you
need to have a serious talk with your fellow developers.)
Let’s agree that, starting right now, you will pass all function arguments as a const
reference, unless you have a good reason not to. Your future colleagues will like you a
lot more when you do so.
And what is a good reason not to use a constant? Look at the Esenthel Clamp
function:
void Clamp(Vec2 & value, C Vec2 & min, C Vec2 & max);
This function will change the first argument when its value is lower than the second
or higher than the third. It can be used like this:
Vec2 pos = Ms.pos();
Clamp(pos, Vec2(-0.4,-0.4), Vec2(0.4,0.4));
pos.draw(RED);
The second and third argument are constant, so the function will never change the
minimum or maximum. But the first argument is the one that is meant to change. No
const reference there.
Exercise
- Search the Engine code for more functions with non-const references. Try
to explain why these references are not constant.
- Write a function ‘ClampToScreen’ which changes an argument (a Vec2)
when it would be outside the screen. Test your function with a simple
program. Can you use a const reference?
- Write a function with a string argument. The function will draw the string
on the screen. Create a version with a const reference and one with a
non-const reference. Test both versions with existing Str variables as well
as with string literals. Why won’t the non-const version work with string
literals?