Semantically, should "setters" in C++ use constant parameters, even for built-ins?

Started by
29 comments, last by Hodgman 15 years, 1 month ago

void setX (const int x)
{
   _x = x;
}
To whomever is calling this function, the fact that x is const doesn't change a thing (though if x weren't a simple non-reference int, that would be a different story). However, x is not going to be changed in the function, so semantically, it seems it should be const. What do you think?
I love the 'nets.
Advertisement
Yeah, that's how I would write it (note: I never did until we started using Lint).

The compiler will still generate the same code, though. So it's only for your own convenience/annoyance (depending on the circumstances... there were many times I had to remove const on such parameter, because I was intentionally fiddling with it within a function)
When talking about integral types or even iterator types then it is just a matter of personal preference which does not gain you anything. Personally I would always add constant and even the reference modifiers here, it is more times than not instinct rather than a process of thought, a coding habit you could say. Having said this, if I were to write a function like your example I would have to question (I realise it is for example purposes) why I was even writing it, why not just make it publicly assessable.
More typing makes me a sad panda. =/
I used to pass built-in types by constant reference, but over time I began to find it ugly and the negligible performance boost (if any) wasn't really worth it.
Quote:Original post by iaminternets
void setX (const int x){   _x = x;}

To whomever is calling this function, the fact that x is const doesn't change a thing (though if x weren't a simple non-reference int, that would be a different story). However, x is not going to be changed in the function, so semantically, it seems it should be const. What do you think?
You're passing by const-value. This is pointless as you're getting a copy of x and then promising to not modify the copy.

Setters should either pass by const-reference or pass by value:
void setX (const int& x)void setX (int x)
Quote:Original post by Hodgman
Quote:Original post by iaminternets
void setX (const int x){   _x = x;}

To whomever is calling this function, the fact that x is const doesn't change a thing (though if x weren't a simple non-reference int, that would be a different story). However, x is not going to be changed in the function, so semantically, it seems it should be const. What do you think?
You're passing by const-value. This is pointless as you're getting a copy of x and then promising to not modify the copy.

Setters should either pass by const-reference or pass by value:
void setX (const int& x)void setX (int x)


Be fair; I made note of the fact that const int x means nothing to whomever is calling the function!

Semantically, I made x const because it isn't changed in the function, though I'm wondering whether it's not considered good practice.

As a side note, I didn't make x a reference because I don't see what it adds semantically (or performance-wise).
I love the 'nets.
I wouldn't use const just because something doesn't change, instead I use it to ensure that something doesn't change when the design dictates that it mustn't.
In this case, it doesn't matter if you change your local copy, so there is no need to enforce that constraint (over-engineering).

[edit] Sorry if my previous post seemed harsh - I didn't mean any offense, I was just trying to be factual.

[edit2] After working as a maintenance coder, I've come to see arguments such as "const int x" as a likely bug because it has no effect on the design (just as linux kernel coders have come to see "volatile" as an indicator of buggy code).
In many cases, it has turned out to be a typo and the author actually meant to use a const-reference ;)

[Edited by - Hodgman on March 12, 2009 8:19:34 PM]
I agree with Hodgman here. A big part of your coding style should be used to help a reader of the code understand what you are trying to do. Implying that a parameter passed by value shouldn't be modified should mean that there's a reason for it which, in this case, there isn't one. This could be confusing. Someone reading the code would have to think, "Now why did they do that?". However, making a parameter that is passed by reference either const or non-const does confer your original intent (as well as enforce your intent in the code, but that's not my point here) and would be helpful to someone else reading the code.
I personally leave the const out. In function declaration its better to leave it out.

For the definition of the function, as mentioned, it doesn't make difference to caller. That said, having const value parameter still has advantages. Analyzing code can become easier, as one doesn't have to "scan" the code to figure out if it is been changed. Same applies for defining local variables as const aswell.

So for the sake of clarity, I sometimes add the const.

This topic is closed to new replies.

Advertisement