Sign in to follow this  
DudeMiester

C++: Why Use const?

Recommended Posts

Um...well, first reason: so things DON'T CHANGE. If you don't want things to change, you const them. Things can change other things sometimes, and if a filename gets accidentally changed (because of your bad coding practices), you'll wish you had constified it.

There's probably more, and I bet Oluseyi can point them out for you. He's smert smart.

Share this post


Link to post
Share on other sites
one other thing is that the compiler can usually optimize better because it knows the intentions for a particular constant, eg. 'const int', rather than just 'int' tells the compiler that that identifier will never change, and maybe if you use it several times in a calculation, the compiler can keep it in a register etc. etc.

so basically, its to make things clearer to you AND the compiler.

Share this post


Link to post
Share on other sites
Another useful use is passing variables by reference. You usually don't want to pass a Vector by value because of the copy overhead. But if you pass a Vector&, the called function can mess with it, which you may not want. So you pass it as a const Vector& - low overhead, and safe.

You can also declare member functions as constant, which means that the function won't change any of the member variables. The compiler can do some optimizations this way.

Also, you can safely call a const function on a const object or const object&. More generally, you build a 'chain of consts' that runs through your code and keeps you from modifying things you shouldn't. It's just good practice, and makes your code safer and more robust.

Share this post


Link to post
Share on other sites
Quote:
Original post by Boku San
There's probably more, and I bet Oluseyi can point them out for you. He's smert smart.
Thanks for the endorsement! [smile]

const indicates that the value contained/referred to by the variable can not be altered. In other words, it makes the variable non-mutable. This has many incarnations:
  • Simple constants, recommended as a replacement for preprocessor defines: const int PI = 3.142;

  • The type for references to literal values. If you want to be able to pass both a std::string and a string literal to a function, then you need a const std::string & parameter.

  • A qualifier for class methods indicating that they will & can not modify the object instance, making them permissible to call on const objects:

    class X
    {
    int retrieveSomethingOrOther(int param) const;
    };

One additional caveat to using const effectively is pointers. Consider the following:
const int * p = &someIntVariable;
const int const * p2 = &someIntVariable;
The first allows the modification of the value pointed to, but not the pointer itself. The second allows neither.

Share this post


Link to post
Share on other sites
Than a non-const variable, particularly if it is, say, an int and the constants is known at compile-time. Instead of creating a variable holding, say, the value 42, it'll directly use 42 in the code. Like a macro in C, except better.

Also worth mentioning is that, since the compiler knows the constant is ... constant, it can apply optimizations it wouldn't if it didn't know that.

So, const can make your code faster.

Share this post


Link to post
Share on other sites
Well, here's a few expert opinions...
the first from sutter on const-correctness and optimization. However, you should beware of typedefs and const as it can have unexpected consequences. Lets also not forget about object lifetimes while we're at it. Finally, and somewhat related, you should really preffer iterator over const_iterator.

Share this post


Link to post
Share on other sites
Edit: Washu beat me to it.




Herb Sutter (whom I refer to as "the man" when it comes to C++) sums up the majority of const related issues in his Guru of the Week article #81

The excellent summary at the end:

Quote:
From Herb Sutters article:

It's a common belief that const-correctness helps compilers generate tighter code. Const is indeed a Good Thing, but the point of this issue of GotW is that const is mainly for humans, rather than for compilers and optimizers. When it comes to writing safe code, const is a great tool that lets programmers write safer code with compiler checking and enforcement. Even when it comes to optimization, const is still principally useful as a tool that lets human class designers better implement handcrafted optimizations, and less so as a tag for omniscient compilers to automatically generate better code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
One additional caveat to using const effectively is pointers. Consider the following:
const int * p = &someIntVariable;
const int const * p2 = &someIntVariable;
The first allows the modification of the value pointed to, but not the pointer itself. The second allows neither.


Oh happy day when I get to correct Oluseyi!!!

The above code should be:
const int * p = &someIntVariable;
const int * const p2 = &someIntVariable;


If you want the pointer itself to be const, rather than the object pointed to, you need to put const after the *.

Compile the following code in any decent C++ compiler, and the errors will explain what I mean:


class A
{
public:
A() : x(0) {}
int x;
};

int main(int argc,char* argv[])
{
A array[2];

A* p = array;

p->x++; // <- Allowed
p++; // <- also allowed

const A* cp1 = array;
A const* cp2 = array;

cp1->x++; // <- Disallowed, Object is const
cp1++; // <- Allowed, pointer is mutable

cp2->x++; // <- Disallowed, Object is const
cp2++; // <- Allowed, pointer is mutable

A* const pc1 = array;
const A* const pc2 = array;

pc1->x++; // <- Allowed, Object is mutable
pc1++; // <- Disallowed, pointer is const

pc2->x++; // <- Disallowed, Object is const
pc2++; // <- Disallowed, pointer is const

return 0;
}

Share this post


Link to post
Share on other sites
I read those sites, and one of the things I noticed is that if you have a globally optimizing compiler it negates most of the optimization benifits of using const. Since I'm using MSVC++ 7.1 I have that feature. Still I can see it's uses.

Also, if I have a function:
const T f(){return T();}
Will the compiler skip over T's copy constructor and basically turn const T f() into T& const f(), but without the issue of returning a temporary?

Share this post


Link to post
Share on other sites
Quote:
Original post by DudeMiester
Also, if I have a function:
const T f(){return T();}

Will the compiler skip over T's copy constructor and basically turn const T f() into T& const f(), but without the issue of returning a temporary?


That's RVO. Which I trust most compilers worth their salt can do.
I actually have some code that does rely on it for correctness... (with a workaround if it's not available)

Share this post


Link to post
Share on other sites
Quote:
Original post by silvermace
Quote:
Original post by UfoZ
Quote:
Original post by Oluseyi
const int PI = 3.142;


Is that an Alabama pi?
[grin]


_ROFL_, i love typos!


How is that a typo? Pi is equal to 3.142 to four significant figures, because the five after the one makes the one round up to a two.

Share this post


Link to post
Share on other sites
Quote:
Original post by furby100
Quote:
Original post by silvermace
Quote:
Original post by UfoZ
Quote:
Original post by Oluseyi
const int PI = 3.142;


Is that an Alabama pi?
[grin]


_ROFL_, i love typos!


How is that a typo? Pi is equal to 3.142 to four significant figures, because the five after the one makes the one round up to a two.


Thats not the problem, its assiging a floating point number to an integer, harmless mistake maybe some caffeine would have help at the time.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
Quote:
Original post by furby100
Quote:
Original post by silvermace
Quote:
Original post by UfoZ
Quote:
Original post by Oluseyi
const int PI = 3.142;


Is that an Alabama pi?
[grin]


_ROFL_, i love typos!


How is that a typo? Pi is equal to 3.142 to four significant figures, because the five after the one makes the one round up to a two.


Thats not the problem, its assiging a floating point number to an integer, harmless mistake maybe some caffeine would have help at the time.


Wow, I must be near sighted.

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
const int * p = &someIntVariable;
const int const * p2 = &someIntVariable;
The first allows the modification of the value pointed to, but not the pointer itself. The second allows neither.



Isn't that because the left hand assignment of a modifier affects the right side?

WINAPI LPVOID Proc(LPARAM lparam,LWPARAM lwparam);

the LPVOID or long pointer void is assigned after the WINAPI ....

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this