samol
samol

Reputation: 20570

How to declare a C++ variable should be mutated

Recently, I had a bug where, we changed the function from

void update_waypoint_heading(const double new_observation, waypoint)
{
   // ....
   waypoint.heading = default_heading_deg * waypoint.some_magic_number
}


// Call the function and the function will calculate new heading and mutate heading in waypoint
update_waypoint_heading(new_observation, waypoint);

to

double update_waypoint_heading(const double new_observation, waypoint)
{
   // ....
   return default_heading_deg * waypoint.some_magic_number
}

// Here the caller is supposed to be responsible for mutation
waypoint.heading = update_waypoint_heading(new_observation, waypoint);

We had a bug where we changed the function but did not change the caller. So we ended with

update_waypoint_heading(new_observation, waypoint);

Where update_waypoint_heading started to return the new heading. But it never got set to the waypoint. This was also perfectly legal for the compiler.

Is it possible to declare a parameter as mutant (like the opposite of const), where it will throw a compiler error if it does not get mutated. So that I can catch these cases at compile time

Upvotes: 0

Views: 376

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

No, and it wouldn't make much sense either.

You pass an argument into a function, and want a keyword to mandate that the calling scope then assigns the result of that function into some part of the same thing you passed as an argument?

This is very convoluted.

If a function returns a result that ought to be used, then that is documented by its return type. If it modifies its by-reference arguments, then that should also be documented. Do not switch from one to the other after you've already got code using that function!

HOWEVER! There is the nodiscard attribute which will prevent the result of calling the function from simply being, well, discarded. That would have flagged this case up, and may be what you're really looking for.

You'll need a nice C++17 compiler to use it.

I still think this is a bit leaky, though. It's not up to your function to decide what the calling scope does with its result. Just don't change function semantics! Write a new function with a new name if you need to. "Update" is no longer a good descriptive name for what it does anyway.

Upvotes: 4

Related Questions