Home arrow C++ arrow Who`s Afraid to Be Const Correct? Help Your Compiler Help You
C++

Who`s Afraid to Be Const Correct? Help Your Compiler Help You


In programs and commercial libraries that are not const-correct, you may find that const_cast is used. While a programmer may do this to force an application to do what he wants it to, it is never a good idea. Jun Nakamura explains why.

Author Info:
By: J. Nakamura
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
August 30, 2005
TABLE OF CONTENTS:
  1. · Who`s Afraid to Be Const Correct? Help Your Compiler Help You
  2. · The Compiler is Your Friend
  3. · Why Use the Compiler to Catch Errors?
  4. · Conclusion

print this article
SEARCH DEVARTICLES

Who`s Afraid to Be Const Correct? Help Your Compiler Help You
(Page 1 of 4 )

CONST_CAST

Unfortunately there are commercial libraries available that are not const-correct. This is not an excuse for you to skimp on const-correctness, but it is one of the excuses to use const_cast.

A nasty cast it is, and it should catch your attention whenever you see it appear in code. The const_cast is a contract-breaker; it is a crowbar that you use when you want to make sure something is done your way. 

My skin crawled when I noticed const_cast being used in a well-known middleware package:

void SomeClass::foo(AnotherClass const *ptr) {

 m_data.pAnother = const_cast <AnotherClass *>(ptr);

}

Definitely the way const_cast is used in this function is a heavy breach of contract. I will even claim that the function is misleading and lying to you! When you study the interface of ‘SomeClass’ as declared in its header file, you expect to be able to safely pass a pointer to ‘AnotherClass’ that has the ‘foo()’ member function when you see that it is declared as:

  void foo(AnotherClass const *ptr);

It clearly states that no changes will be made to the object you are passing in via a pointer.

But you have surrendered it unknowingly into the hands of ‘SomeClass’ that can do with it however it pleases, and you won’t know it until you take a look at the implementation of foo! This is clearly a case where the code is very const-incorrect, and pretends to be safe while it silently hijacks your object. The results of the const_cast are even undefined when the object passed in was originally declared as a const object!

I think that the creator of the library should either fix the code, or when the code base is simply too large and the consequences too far stretching… maybe just get rid of const altogether (or at least leave a big fat comment in the header file). I’d rather not get any directions when asking for them, instead of being sent the wrong way!

The First CONST_CAST Excuse

When you are using a commercial package that is not const-correct, you can use a const_cast so you can properly connect to its interface. Some libraries are known to implement strlen as: size_t strlen(char *s);

As long as you can correctly verify that your object won’t be modified, you can safely cast const away.

Make sure you only do this in the immediate layer connecting to code that is not const-correct, for it will affect your own code otherwise as well!

The Second CONST_CAST Excuse

The second reason is quite an exotic one. When you remain conceptually const-correct (it is not observable from outside that data members are changed in the object… e.g. when caching the length of a label – see previous article) you will need the ‘mutable’ keyword. But how do you modify a const member data when your compiler doesn’t support the ‘mutable’ keyword?

You can cast const away from the ‘this’ pointer, which is either declared as ‘MyClass  * const this;’ for non-const member functions or as ‘MyClass const * const this;’ for const member functions. Warning: you’re playing with fire now!

Here is a ‘mutable-free’ implementation of the ‘GetLabelLength’ function:

size_t MyClass::GetLabelLength() const {

if (-1 == m_LabelLength) {

 MyClass* const self=const_cast<MyClass* const>(this);

self->m_LabelLength = strlen(m_pLabel);

  }

return m_LabelLength;

}

Note that this is not always guaranteed to work. When the instanced MyClass object was declared const at its point of definition, the results of casting const away are undefined! (See also Item 21 “Use const whenever possible” [Meyers]).

At least you can recognize this hack now when you stumble upon it.


blog comments powered by Disqus
C++ ARTICLES

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials