Reputation: 937
I want to use a function parser library where the member function FunctionParser::Eval()
is non-const, because it writes an error code to a member variable. I would like to integrate this function parser into a codebase, where this function would get called through a const
member function of a class holding that function parser, thus violating const
correctness.
This const
member function is part of an interface, where the const
ness makes semantic sense. I could change that interface, so that remains an option.
As a test, I used const_cast
to execute the code violating const
correctness, which did not cause any errors or failed unit tests (at least not in Debug mode).
Now my question is: What problems down the road should I expect when violating const
correctness in this case? (And would that ever be worth it?)
Upvotes: 2
Views: 179
Reputation: 206577
What problems down the road should I expect when violating const correctness in this case? (And would that ever be worth it?)
If the object in question was constructed as a const
object, then you definitely run into undefined behavior. However, if the object was constructed as a non-const
object, then using const_cast
to call a non-const
member function is OK.
Simple example:
struct Foo {int f; };
void testFoo(Foo const& foo)
{
const_cast<Foo&>(foo).f = 10; // Analogous to calling a non-const member function.
}
int main()
{
Foo obj1 = {20};
Foo const obj2 = {30};
testFoo(obj1); // ok. obj1 was constructed as a non-const object.
testFoo(obj2); // Not ok. obj2 was constructed as a non-const object.
}
Upvotes: 1
Reputation: 17454
You're not violating const-correctness; you're merely bypassing the built-in language checks for it.
Modifying a non-const
thing is fine, even if you had to cast away some const
ness somewhere along the way (indeed, this is what const_cast
is for).
This is generally considered to be a dangerous thing to do, though, and dangerous code to write, so you should modify your interface or design. (This sounds like a good use case for mutable
.)
But what runtime errors or weirdness can you expect right now? None at all.
Upvotes: 1
Reputation: 168988
If the object is actually defined const, then casting away const-ness to modify the object is undefined behavior.
Consider instead using the mutable
keyword, which declares an exception to const-ness for a given field; a mutable
field is always non-const even when accessed on an object that is considered const in the current context (including from within const methods).
class foo {
private:
int a; // cannot be modified on a const foo
mutable int b; // CAN be modified on a const foo!
};
You could use the mutable
keyword for fields related to error tracking.
Of course, a better pattern would be to throw an error object if an error occurs. If your API design does not permit this, making the relevant fields mutable is the correct workaround.
Upvotes: 8