From my knowledge (and this topic: When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?) const_cast
is the only cast that should be able to take away constness of a variable. However, when messing around with clang-6.0
and g++5.4.0
I stumbled upon a behaviour that would contradict the above. It seems static_cast
does exactly the same job.
These main functions give the exact same results with both compilers:
test class definition
struct Base {
Base() {
std::cout << "Base::Base()\n";
}
void test() const {
std::cout << "Base::test()\n";
}
void no_const() {
std::cout << "Base::no_const()\n";
}
virtual ~Base() = default;
};
with const_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
const_cast<Base&>(b).no_const();
std::cout << "END\n";
}
with static_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
static_cast<Base>(b).no_const();
std::cout << "END\n";
}
Result:
BEGIN
Base::Base()
Base::no_const()
END
What gives?
Add a copy constructor definition for Base
, it'll answer your question.
Base(Base const&) {
std::cout << "Base::Base(Base const&)\n";
}
The output from your second example changes to
BEGIN
Base::Base()
Base::Base(Base const&)
Base::no_const()
END
Attempt to cast away constness from b
itself, and you'll see an error
static_cast<Base&>(b).no_const();
// ^
error: invalid
static_cast
from type 'const Base
' to type 'Base&
'static_cast<Base&>(b).no_const();