C++: Why Use const?

Started by
32 comments, last by snk_kid 19 years, 5 months ago
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.
Advertisement
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.
const variables at namespace scope also have internal linkage by default.
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.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
Quote:Original post by Oluseyi
const int * p = &someIntVariableconst 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 ....
--What are you nutz?I have nothing to say to your unevolved little brain. The more I say gives you more weapons to ask stupid questions.
Ok I have this weird issue. Basically what I have is this:

const T func1(){    T Result;    return Result;}const T func2(){    return T();}


Now I would figure both functions would be identical, but upon testing it turns out that func2 is about twice as fast as func1, because func1 doesn't use RVO that Fruny was talking about. So do I have to write my functions in the forum of func2 to take advantage of this feature?
[s] [/s]
I can see the fnords.
One example on how the compiler can use const to optimize your code:


struct S
{
int a;
int b;
}

...

S s;
s.a = xxx;
s.b = yyy;
doStuff(s);
...
doStuff(s);
...
doStuff(s);


Assume that doStuff is declared like this:


void doStuff(S& s);


At the first call to doStuff, the compiler must store the variable s onto the stack. Since s is used later and the compiler can't know if something in the doStuff is being modified. The code becomes something like this:


put s.a in eax
put s.b in ebx
push eax
push ebx
call doStuff
mov ebx,[esp + 0]
mov eax,[esp + 4]
call doStuff
mov ebx,[esp + 0]
mov eax,[esp + 4]
call doStuff


If the definition of doStuff is:


void doStuff(const S& s);


You're telling the compiler that s doesn't change during the call and the code could be optimized, more like:


put s.a in eax
put s.b in ebx
call doStuff
call doStuff
call doStuff


This is one place where the const keyword helps the compiler to perform better. And belive me it does. Using const were applicable is really creating better code. I use it everywhere I can.
I realise that, but that doesn't solve my problem. Well it's not so much a problem as an incovienance.
[s] [/s]
I can see the fnords.
You might find the above code funny, but in practive this is very common when using member variables, consider:

struct
{
void a(void)
{
int temp2 = m_data + 17;
...
b();
..
int temp = m_data + 1;
}
void b(void)
{
}
int m_data;
};

In method a, where b is called the compiler must invalidate all member variables stored in registers, because the b method could invalidate some or all of them. If b was const'ed, the compiler know that m_data couldn't be invalidated by the call to b and thus m_data could persist in a register.

In some cases accessing the member function just once in every method is faster, often the code:

void a(void)
{
int data = m_data;
int temp2 = data + 17;
...
b();
..
int temp = data + 1;
}

Is faster, since this basicly tells the compiler that we don't care if b modifies m_data.
Quote:Original post by Anonymous Poster
One example on how the compiler can use const to optimize your code:


struct S
{
int a;
int b;
}

...

S s;
s.a = xxx;
s.b = yyy;
doStuff(s);
...
doStuff(s);
...
doStuff(s);


Assume that doStuff is declared like this:


void doStuff(S& s);


At the first call to doStuff, the compiler must store the variable s onto the stack. Since s is used later and the compiler can't know if something in the doStuff is being modified. The code becomes something like this:


put s.a in eax
put s.b in ebx
push eax
push ebx
call doStuff
mov ebx,[esp + 0]
mov eax,[esp + 4]
call doStuff
mov ebx,[esp + 0]
mov eax,[esp + 4]
call doStuff


If the definition of doStuff is:


void doStuff(const S& s);


You're telling the compiler that s doesn't change during the call and the code could be optimized, more like:


put s.a in eax
put s.b in ebx
call doStuff
call doStuff
call doStuff


This is one place where the const keyword helps the compiler to perform better. And belive me it does. Using const were applicable is really creating better code. I use it everywhere I can.


This is unfrotuantely not true. Unless the compiler knows the definition of doStuff() and can verify that s.a and s.b indeed do not change, this is an invalid optimisation, and can produce incorrect behaviour.

If I (stupidly, granted, but still possible and legal code) decide do make doStuff() do this:

doStuff(const S &s) {
S *nonConstS = const_cast<S*>&s
nonConstS.a += 5;
}

Then the code will no longer behave as expected. This is not the programmers fault, but the compiler's fault for doing an incorrect omptimsation based on things it doesn't know enough bout.

The appearance or lack of const will not help the compiler one iota in this situation optimise your code, unless the compiler already knows the body of doStuff() and can verify that nothing changes.

This topic is closed to new replies.

Advertisement