As I try to apply const-correctness for my own code, I often have to add const
qualifications to function definitions in other modules (written by other programmers) in order to use those functions in my own code. (see here on back-patching const-correctness)
I always thought that if everything compiles fine, this could impossibly lead to broken functionality as const
labels only matter at compile time.
Yet, the other day one of my colleagues insisted that I should rerun all automated tests before I commit code with added const
labels, where I thought it was sufficient that such code compiled.
Does he have a point? Is there a way that applying const-correctness could break existing functionality ?
Edit: It is maybe important to note that, generally, I only have to do this for pointer parameters of functions (e.g. Something getSomething(Object* pObj)
to Something getSomething(const Object* pObj)
. I do not change return types or method constness as this is not a problem for client code.
They do indeed have a point.
If you cast away const
ness from a variable that was originally const
, then the program behaviour is undefined. You risk introducing that into your code if you add const
qualifications.
You might unintentionally switch function overloading for function overriding.
Passing an anonymous temporary to a function that takes a const
reference is defined, but if the function takes a non-const
reference then the behaviour is undefined. Many compilers permit the non-const
(possibly accidentally although some even go as far as calling it an extension). Ostensibly, you're doing everyone a favour in fixing this, but you might be removing an undefined-behaviour construct that is relied upon at runtime.
The C++ standard does not insist that sizeof(T*) == sizeof(const T*)
. Your class' v-table layout could be different on your making a non-const
to const
parameter switch. Granted, it's unlikely, but you must test.
In summary, you must test these changes.
As const method may differ than non const one
class C
{
public:
int& get() { return i; }
int get() const { return i; }
private:
int i = 42;
};
you may have different bahavior:
C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // true
whereas
const C c;
auto&& p1 = c.get();
auto&& p2 = c.get();
assert(&p1 == &p2); // not true.
Yes.
One possible problem with adding const
s is possible undefined behaviour when changing the variable later (in a situation where the compiler can't prevent it anymore).
What if f is const here?
float f = 1.0;
//do something with f
readFromBinaryFile((char *)(&f), sizeof(f));
//do another something with f
//...
void readFromBinaryFile(char *c, size_t s)
{
//... fill c
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With