const clarifications wanted...

Started by
11 comments, last by Zahlman 18 years, 11 months ago
Hi, Correct me if I'm wrong please: - void class::Dummy(const Object *o) {...} Nice from an API design point of view, explicitly declares that the object won't be modified. Some place for optimisation. - void class::Dummy(const Object * const o) {...} More place for optimisation since o is guaranteed not to change (?). Is it worth the trouble to go from 'const *' to 'const * const' where possible and... - GCC does not require the const * const form to be declared both in the header and implementation, what about other compilers? Thanks!
Praise the alternative.
Advertisement
Quote:- void class::Dummy(const Object *o) {...}
Nice from an API design point of view

Correct, but forget the optimization part. Unless you use the -no-aliasing compiler flag you'll probably not see any optimization based on the const.
This is a subject that can be discussed in length. But the basic problem is that the compiler cannot be sure that the const reference is _the only_ reference to that object. You could have another non-const-reference somewhere that modifies the object. And hence, the compiler cannot cache the object's values even when it's const. With the -no-aliasing flag the compiler assumes that no memory is accessed through more than one reference. This is a very dangerous assumption, so it's not wise to use the flag. =)

Quote:- void class::Dummy(const Object * const o) {...}

This is a completley different type. Now the pointer itself is const, not only the object it points too. This is usually not what you want.

[edit]To conclude: It's not worth the trouble to use 'const * const' even when possible. And if you need the code to be optimized don't rely on the compiler[/edit]
Quote:Original post by greldik
This is a completley different type. Now the pointer itself is const, not only the object it points too. This is usually not what you want.

Indeed, it would be like passing in "const int" - pretty pointless.
Quote:Original post by Andrew Russell
Quote:Original post by greldik
This is a completley different type. Now the pointer itself is const, not only the object it points too. This is usually not what you want.

Indeed, it would be like passing in "const int" - pretty pointless.


But in theory at least, a "const int" can be optimized, because it is guarenteed not to be changed, and the same goes for a pointer. Whether or not it works in practice, I don't know.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Okay, got that. Thanks.
Praise the alternative.
Oh and, pure curiosity but, do you have an example of where the 'const * const' form might be better?
Praise the alternative.
Quote:Original post by swiftcoder
But in theory at least, a "const int" can be optimized, because it is guarenteed not to be changed

No.

A non-const int is guarenteed not to change, because it's passed by value (a copy is made). Making it const dosn't provide any extra guarentees to the caller. It only places a limitation on the implementation of the function.

Which is the reason that the implementation can remove the const as b34r said in his first post. It is because the compiled code is exactly the same.
Quote:Original post by b34r
Oh and, pure curiosity but, do you have an example of where the 'const * const' form might be better?

A reference or pointer to a const pointer to a const object.

The actual value passed to the function is always passed in by value (pretend references are pointers here - they basically are in compiled code anyway). This means making the "head" of a type of an argument const is pointless.

In other words, when passing in a pointer to an object, the pointer itself is passed in by value - that is - a copy is made. Because of this - it dosn't matter if it's const or not - the caller knows it can't be changed.
First, const is more or less just a mean to clarify your code, no optimizations can be concluded from using const.

Quote:It only places a limitation on the implementation of the function.


Yes, but that limitation could be quite useful.
Consider having a function like this:
void foo(int bar){  int a = bar * 10;  if (a < 10){     b = 20 + bar;  }else {     a = 12 * bar * bar;     if (bar = 10 * a)        a -= bar * 5;  }  doStuff(a);}voidmain(void){  foo(10);}// I'd like to add some code to the end of the function, testing the input parameter bar for some value:void foo(int bar){  int a = bar * 10;  if (a < 10){     b = 20 + bar;  }else {     a = 12 * bar * bar;     if (bar = 10 * a)        a -= bar * 5;  }  doStuff(a);// If bar input is 10 do some extra stuff.  if (bar == 10)    doExtraStuff(a);}voidmain(void){  foo(10);}


doExtraStuff is never executed in the later example, why?
Because there is an assignment to bar in the code.
Found it? if (bar = 10 * a)
To add code using bar, you need to serach the code to make sure that bar isn't modified somewhere.
With lot's of code, this takes time and it's quite easy to miss an assignment.
Using (const int bar) in the above, the code wouldn't compile without complaints.

Indeed my original intention wasn't to assign bar a new value, but rather doing a normal compare: if (bar == 10 * a)

Using the const keyword does clarify the intention of the code and can help you to avoid some logical bugs.

Just my 2c
Quote:Original post by eq
doExtraStuff is never executed in the later example, why?
Because there is an assignment to bar in the code.
Found it? if (bar = 10 * a)

Very clever! If only it wasn't such a mess to use the const keyword everywhere. If you stuck to this design rule, const would easily be the most frequently used word in your project, perhaps doubling other words. I think the language designers should have defaulted function parameters to const and gave us a modifiable keyword [smile]

This topic is closed to new replies.

Advertisement