For a struct
with const
members
struct point { const int x; const int y; };
that is used as member data
This is clearly undefined behavior. Now, "can" this be done? Sure, it can, but only in the sense that the compiler will not complain. But one aspect of C++ is just because the compiler doesn't complain it doesn't mean that the resulting code will work right.
It's only a matter of time before someone writes some code that reads pt
, calls move_x()
, and then reads pt
again.
A modern, optimizing compiler will rightfully assume that because the code is reading const
instances, their values cannot change, and then proceed and optimize away the second read from pt
, using the data cached from the first read of pt
, in the CPU registers.
And then, the hapless programmer will spend a week trying to figure out why the code is clearly not doing what the program says it should be doing.
You will get a compiler error trying to use memcpy
with a const
member as follows:
#include <cstdlib>
#include <cstdio>
#include <cstring>
struct foo
{
public:
foo(int init_x);
const int x;
int bar();
};
foo::foo(int init_x): x(init_x) {}
int foo::bar()
{
int *y = (int *) malloc(sizeof(int));
*y = 6;
memcpy(&x, y, sizeof(int));
return x;
}
int main(int argc, char *argv[])
{
foo f{5};
printf("%d\n", f.bar());
}
The above results in
error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
memcpy(&x, y, sizeof(int));
While I used const int
in this example, you will find the same result if you instead use a const int
pointer member, i.e.
const int *x;
But, if you remove the const
descriptor and use:
int x;
(or int *x;
, for that matter) the error no longer happens, and the program prints 6
, as one might expect.
So this begs the question, if you know something is going to be declared as const
:
const
yourself?const
makes?