Thursday, June 23, 2011

Short little post about C++ const-correctness

Ok, so I don't really like the concept of "const-correctness" in c++, but I never really had a solid reason to dislike it besides laziness. Hence I never really bother to mark class functions as const (except in basic numerical types like Vec2D) unless the compiler whines about it.

Well, until yesterday that is. I was writing a rational number class for the hell of it (mostly as a little exercise for myself). Internally, it's represented as a numerator and denominator value. Now here's the thing: Rational(10, 4) and Rational(5, 2) are effectively identical and behave exactly the same way as far as any user could tell, even if they're represented different internally. A function, Rational::reduce(), changes the internal representation of the number without actually changing the value of the number. For all intents and purposes, this function is constant.

A few operators require reducing the rationals first, notably operator== (which most would agree should be a constant function).

Yet, reduce can't be labeled const because it changes numerator and denominator, therefore operator== either has to work with temporaries or also can't be labeled const.

- Marking numerator and denominator as mutable, but that's just stupid and unsafe since at this point you basically completely throw the notion of const correctness out the window and you may as well just not mark anything as const [which ends up happening in most of my personal projects].

- const_cast<Rational*>(this)->numerator = blahblahblah
[this is quite ugly, though it does work]

void reduce(){ //reducenumbercodehere }
void reduce() const {const_cast<Rational*>(this)->reduce();}
[this is also ugly and boilerplate-y]

What c++ SHOULD have is a way to mark a function as "mutable const". We can do it with variables already, why not also with functions? Yes it could be abused but so can mutable variables and const_cast.

I'm sure there's other examples of this problem occurring, but I figured this is a pretty easy to understand real-world example.


Anonymous Anonymous said...

It seems to me the thing you're asking for (mutable support on functions) is something that makes sense if you assume "const" is a thing there for programmer convenience. It's not though as I see things, const is a compiler optimization thing. By marking something const you're making a promise to the compiler that it can make assumptions about some particular piece of data, by then marking something mutable you're declaring an exception and saying "but you can't make the assumption for these bytes". But if *functions* get the mutable exception, then either it invalidates the const assumption for the whole object or at least invalidates forever the const assumption for the fields the mutable-function touches, at which point you might as well just mark the appropriate fields mutable and mark the function const.

I think just leaving == non-const is the correct thing to do in this case-- == really *isn't* a const operation for this type, so don't pretend it is one. Another, slightly crazier option is that you could declare 2 == functions for the type, one const, one not (I'm 90% sure C++ function overloading lets you do this?), the const== would do the reduction in temporary variables that get thrown away, the nonconst== would do the more efficient operation of reducing the numerator/denominator fields in place and leaving them that way.

- mcc

June 23, 2011 at 3:09 PM  
Anonymous Anonymous said...

...actually, having said that, I ran across this discussion and some links: which it's argued the const keyword is actually of little or no use to compilers except sometimes when objects are defined inline in code.

- mcc

June 23, 2011 at 4:38 PM  
Blogger madin said...

Réplique de haute qualité replique montres d'un horloger digne de confiance? ici peut vous offrir la meilleure réplique de montres Omega en haute qualité, y compris Cartier, Breitling, etc.

April 15, 2018 at 11:59 PM  
Blogger Unknown said...

This is such a great resource that you are providing and you give it away for free. I love seeing blog that understand the value of providing a quality resource for free. Fortnite 2018

May 6, 2018 at 12:22 PM  
Blogger john said...

It’s very excellent information and more real facts to provided that post.Thank you for sharing this information. 700-651 Braindumps PDF

November 29, 2018 at 10:55 PM  
Blogger Vicky Ram said...

I am happy to find this post Very useful for me, as it contains lot of information

Article submission sites

January 28, 2019 at 9:50 PM  
Blogger sathyaramesh said...

This post is much helpful for us. This is really very massive value to all the readers and it will be the only reason for the post to get popular with great authority.
Devops Training in Chennai
Devops Certification in Chennai
CCNA Course in Chennai
Cloud Computing Training in Chennai
Data Science Course in Chennai
Devops Training in OMR
Devops Training in Tnagar

April 8, 2019 at 12:35 AM  
Blogger Charlotte W. said...

Global variables were common in early (and more rudimentary) programming languages, but they are now considered bad programming style. The strategy in modern languages is to control as much as possible when and how data can be modified. This helps to reduce the possibility that data is accidentally changed or corrupted somewhere in the program. In other words, it makes your program much easier to debug. Thanks all :)~ Charlotte W. from

January 24, 2020 at 1:04 AM  
Blogger Cleaning Company Dubai UAE said...

Thinking of tired associated with to call several different companies during UAE for the cleaning products needs, You name one provider for maid services like house cleaning, one meant for home institution, one meant for errand services but yet another meant for other family members services. cleaning company in dubai

February 17, 2020 at 6:49 AM  
Blogger aditya said...

Nice post thanks for share article. Frases

September 7, 2020 at 6:07 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home