Sell me on const correctness


Sell me on const correctness



So why exactly is it that it's always recommended to use const as often as possible? It seems to me that using const can be more of a pain than a help in C++. But then again, I'm coming at this from the python perspective: if you don't want something to be changed, don't change it. So with that said, here are a few questions:

  1. It seems like every time I mark something as const, I get an error and have to change some other function somewhere to be const too. Then this causes me to have to change another function somewhere else. Is this something that just gets easier with experience?

  2. Are the benefits of using const really enough to compensate for the trouble? If you don't intend on changing an object, why not just not write code that doesn't change it?

I should note that at this point in time, I'm most focused on the benefits of using const for correctness and maintainability purposes, although it is also nice to have an idea of the performance implications.

EDIT: I'm told that the correct term is const correctness, so that's what the title is now.




Avoiding Dialog Boilerplate in Delphi and /or C++

1:



C++ concatenate string and int
This is the definitive article on "const correctness": https://isocpp.org/wiki/faq/const-correctness..
Is there a way to implement layers in GDI+?
In a nutshell, using const is good practice because....
What is a good use case for tr1::result_of?
  1. It protects you from accidentally changing variables that aren't intended be changed,
  2. It protects you from making accidental variable assignments, and
  3. The compiler can optimize it.


    atoi() conversion error
    For instance, you are protected from.
    Pros & Cons of putting all code in Header files in C++?
    if( x = y ) // whoops, meant if( x == y ) 
At the same time, the compiler can generate more efficient code because it knows exactly what the state of the variable/function will be at all times.


Is CGI in any way bettern than Servlets?
If you are writing tight C++ code, this is good..
How to parse a string to an int in C++?
You are correct in that it can be difficult to use const-correctness consistently, but the end code is more concise and safer to program with.

When you do a lot of C++ development, the benefits of this quickly manifest..


2:


Here's a piece of code with a common error that const correctness can protect you against:.
void foo(const int DEFCON) {    if (DEFCON = 1)     //< FLAGGED AS COMPILER ERROR! WORLD SAVED!    {        fire_missiles();    } } 


3:


It seems like every time I mark something as const, I get an error and have to change some other function somewhere to be const too.

Then this causes me to have to change another function somewhere else.

Is this something that just gets easier with experience?.
From experience, this is a total myth.

It happens when non const-correct sits with const-correct code, sure.

If you design const-correct from the start, this should NEVER be an issue.

If you make something const, and then something else doesn't complile, the compiler is telling you something extremely important, and you should take the time to fix it properly..


4:


It's not for you when you are writing the code initially.

It's for someone else (or you a few months later) who is looking at the method declaration inside the class or interface to see what it does.

Not modifying an object is a significant piece of information to glean from that..


5:


const is a promise your are making as a developer, and enlisting the compiler's help in enforcing.. My reasons for being const-correct:.
  • It communicates to clients of your function that your will not change the variable or object
  • Accepting arguments by const reference gives you the efficiency of passing by reference with the safety of passing by value.
  • Writing your interfaces as const correct will enable clients to use them.

    If you write your interface to take in non-const references, clients who are using const will need to cast constness away in order to work with you.

    This is especially annoying if your interface accepts non-const char*'s, and your clients are using std::strings, since you can only get a const char* from them.
  • Using const will enlist the compiler in keeping you honest so you don't mistakenly change something that shouldn't change.


6:


If you use const rigorously, you'd be surprised how few real variables there are in most functions.

Often no more than a loop counter.

If your code is reaching that point, you get a warm feeling inside...validation by compilation...the realm of functional programming is nearby...you can almost touch it now....


7:


Programming C++ without const is like driving without the safety belt on.

. It's a pain to put the safety belt on each time you step in the car, and 364 out of 365 days you'll arrive safely.

. The only difference is that when you get in trouble with your car you'll feel it immediately, whereas with programming without const you may have to search for two weeks what caused that crash only to find out that you inadvertently messed up a function argument that you passed by non-const reference for efficiency..


8:


My philosophy is that if you're going to use a nit-picky language with compile time checks than make the best use of it you can.

const is a compiler enforced way of communicating what you mean...

it's better than comments or doxygen will ever be.

You're paying the price, why not derive the value?.


9:


const helps you isolate code that "change things" behind your back.

So, in a class, you'd mark all methods that don't change the state of the object as const.

This means that const instances of that class will no longer be able to call any non-const methods.

This way, you're prevented from accidentally calling functionality that can change your object.. Also, const is part of the overload mechanism, so you can have two methods with identical signatures, but one with const and one without.

The one with const is called for const references, and the other one is called for non-const references.. Example:.
#include <iostream>  class HelloWorld {     bool hw_called;  public:     HelloWorld() : hw_called(false) {}      void hw() const {         std::cout << "Hello, world! (const)\n";         // hw_called = true;  <-- not allowed     }      void hw() {         std::cout << "Hello, world! (non-const)\n";         hw_called = true;     } };  int main() {     HelloWorld hw;     HelloWorld* phw1(&hw);     HelloWorld const* phw2(&hw);      hw.hw();    // calls non-const version     phw1->hw(); // calls non-const version     phw2->hw(); // calls const version     return 0; } 


10:


For embedded programming, using const judiciously when declaring global data structures can save a lot of RAM by causing the constant data to be located in ROM or flash without copying to RAM at boot time.. In everyday programming, using const carefully helps you avoid writing programs that crash or behave unpredictably because they attempt to modify string literals and other constant global data.. When working with other programmers on large projects, using const properly helps prevent the other programmers from throttling you..


11:


const correctness is one of those things that really needs to be in place from the beginning.

As you've found, its a big pain to add it on later, especially when there is a lot of dependency between the new functions you are adding and old non-const-correct functions that already exist.. In a lot of the code that I write, its really been worth the effort because we tend to use composition a lot:.
class A { ... 

} class B { A m_a; const A& getA() const { return m_a; } };
If we did not have const-correctness, then you would have to resort to returning complex objects by value in order to assure yourself that nobody was manipulating class B's internal state behind your back.. In short, const-correctness is a defensive programming mechanism to save yourself from pain down the road..


12:


Say you have a variable in Python.

You know you aren't supposed to modify it.

What if you accidentally do?. C++ gives you a way to protect yourself from accidentally doing something you weren't supposed to be able to do in the first place.

Technically you can get around it anyways, but you have to put in extra work to shoot yourself..


13:


There is a nice article here about const in c++.

Its a pretty straight forward opinion but hope it helps some..


14:


When you use the "const" keyword, you're specifying another interface to your classes.

There is an interface that includes all methods, and an interface that includes only the const methods.

Obviously this lets you restrict access to some things that you don't want changed.. Yes, it does get easier with time..


15:


I like const correctness ...

in theory.

By every time I have tried to apply it rigourously in practice it has broken down eventually and const_cast starts to creep in making the code ugly.. Maybe it is just the design patterns I use, but const always ends up being too broad a brush.. For example, imagine a simple database engine ...

it has schema objects, tables, fields etc.

A user may have a 'const Table' pointer meaning that they are not allowed to modify the table schema itself ...

but what about manipulating the data associated with the table? If the Insert() method is marked const then internally it has to cast the const-ness away to actually manipulate the database.

If it isn't marked const then it doesn't protect against calling the AddField method.. Maybe the answer is to split the class up based on the const-ness requirements, but that tends to complicate the design more than I would like for the benefit it brings..


16:


You can give the compiler hints with const as well....as per the following code.
#include <string>  void f(const std::string& s) {  } void x( std::string& x) { } void main() {     f("blah");     x("blah");   // won't compile... 

}


17:


Also without const correctness you can't pass arguments by const reference, which could lead to more copying.

Pass by (non const) reference is not a sollution because non const references cann not be bound to temporaries..



90 out of 100 based on 50 user ratings 750 reviews

@