removing constness of a true const

S

siddhu

I guess removing constness of a true const( I guess it is also called
bitwise const ) using const_cast is undefined behavior. Can you
please give an example of a true const and may be a sample code which
exhibits undefined behavior by removing constness of a true const.
 
V

Victor Bazarov

I guess removing constness of a true const( I guess it is also called
bitwise const ) using const_cast is undefined behavior. Can you
please give an example of a true const and may be a sample code which
exhibits undefined behavior by removing constness of a true const.

Homework? Interview question?

A literal is usually a "true const". So, trying to remove const from
the literal and then change it does have undefined behavior. Give the
example that uses a literal, and you'll solve your own homework.

V
 
S

siddhu

Homework?  Interview question?

A literal is usually a "true const".  So, trying to remove const from
the literal and then change it does have undefined behavior.  Give the
example that uses a literal, and you'll solve your own homework.

V

Thanks Victor for answering!

how about this?


class integer
{
int i;
public:
integer(int ii = 0):i(ii)
{
}
void print()const
{
std::cout<<"integer::i = "<<i<<std::endl;
}
void modify()
{
i = 43;
}
};
bool verifyObjectCorrectness (const integer& obj)
{
integer* iptr = const_cast<integer*>(&obj);
iptr->modify();
}

int main()
{
const integer inti(53);
inti.print();
verifyObjectCorrectness(inti);
inti.print();

const int const_i = 78;
int* iptr = const_cast<int*>(&const_i);
*iptr = 100;

char* c = "Hello Victor"; //allowed in c++ though string litteral
is const char*
c[2] = 'd'; //although some compilers allow this but this is UB I
guess

return 0;
}

My first question is : In the above example, are the objects 'inti'
and 'const_i' true consts ?

If that is the case then does the above example undefined behavior?

as you asked i wrote a sample code for string literal. Please give
your input on this.

Thanks again!
siddhu
 
B

Balog Pal

siddhu said:
I guess removing constness of a true const( I guess it is also called
bitwise const ) using const_cast is undefined behavior. Can you
please give an example of a true const and may be a sample code which
exhibits undefined behavior by removing constness of a true const.

Removing constness is well defined. But actually modifying non-mutable
member of a const object is UB. By any means, including the use of
pointer/ref from const_cast.
 
S

siddhu

Removing constness is well defined. But actually modifying non-mutable
member of a const object is UB. By any means, including the use of
pointer/ref from const_cast.

Thanks Balog!
Does that mean removing constness of 'this' in const member function
is an UB?
 
V

Victor Bazarov

Thanks Victor for answering!

how about this?


class integer
{
int i;
public:
integer(int ii = 0):i(ii)
{
}
void print()const
{
std::cout<<"integer::i ="<<i<<std::endl;
}
void modify()
{
i = 43;
}
};

Class objects are never truly const. When I meant a literal, I meant
not necessarily a character or a string literal. I can be a double
literal or an unsigned long literal.
bool verifyObjectCorrectness (const integer& obj)
{
integer* iptr = const_cast<integer*>(&obj);
iptr->modify();
}

int main()
{
const integer inti(53);
inti.print();
verifyObjectCorrectness(inti);
inti.print();

const int const_i = 78;
int* iptr = const_cast<int*>(&const_i);
*iptr = 100;

That's undefined behaviour.
char* c = "Hello Victor"; //allowed in c++ though string litteral
is const char*
c[2] = 'd'; //although some compilers allow this but this is UB I
guess

Yes, it is.
return 0;
}

My first question is : In the above example, are the objects 'inti'
and 'const_i' true consts ?

If that is the case then does the above example undefined behavior?

as you asked i wrote a sample code for string literal. Please give
your input on this.

I didn't say "string literal", did I?

V
 
B

Bo Persson

siddhu said:
Thanks Balog!
Does that mean removing constness of 'this' in const member function
is an UB?

It is if the object is really const.

Suppose the data is stored in a ROM. What happens when you try to
change it?


Bo Persson
 
V

Victor Bazarov

It is if the object is really const.

Suppose the data is stored in a ROM. What happens when you try to
change it?

I see two concepts here, removing of 'const' and changing. I don't
think that the former is the same as the latter, or is it?

V
 
B

Balog Pal

Victor Bazarov said:
Class objects are never truly const.

How so? You say

const std::pair<int, int> foo = std::make_pair(1,2);

is any less const than two separate ints? Or that overwriting them is less
UB?

I'd be very disappointed if today's compilers would not put that pair in the
'const' segment and fiddling with it would not cause a crash.

Doing the same with std::string is possibly trickier, but if the compiler
substitutes strlen("foo") with 3 at compile, it could create const string
with its supposed state placeable in const data too, if the writers put some
work in.
 
V

Victor Bazarov

How so? You say

const std::pair<int, int> foo = std::make_pair(1,2);

is any less const than two separate ints? Or that overwriting them is
less UB?

I'd be very disappointed if today's compilers would not put that pair in
the 'const' segment and fiddling with it would not cause a crash.

Any data initializing which requires code to be executed at runtime
cannot be put in "the 'const' segment" - the segment would not be const,
would it?
Doing the same with std::string is possibly trickier, but if the
compiler substitutes strlen("foo") with 3 at compile, it could create
const string with its supposed state placeable in const data too, if the
writers put some work in.

V
 
J

Johannes Schaub (litb)

siddhu said:
I guess removing constness of a true const( I guess it is also called
bitwise const ) using const_cast is undefined behavior. Can you
please give an example of a true const and may be a sample code which
exhibits undefined behavior by removing constness of a true const.

Some folks here mentioned literals like double or int literals. But those
are not const, and const cannot meaningfully applied to them.

What "const" means is that the stored value of an object does not change
from one to another value. Changing the object may change the stored value
to something else. "const" prevents such changes to the object.

A value in and of itself does not convey a meaning of "const". Hence, in
C++, non-class and non-array rvalues cannot be const qualified. That makes a
great deal of sense, because they are not objects.

It should be mentioned that the C++ Standard does not know a strict
distinction between "value" and "object". In my text above, I used "value"
in the sense of "the abstract meaning designated by an object's value
representation", as defined by 3.9p4 (sadly that definition of "value" isn't
used consistently throughout the spec or draft).
 
V

Victor Bazarov

Some folks here mentioned literals like double or int literals. But those
are not const, and const cannot meaningfully applied to them.

If the code doesn't know it's a literal, does 'const' apply then?

void foo(const int& i)
{
// is 'i' const here? Can we cast away its constness?
int& ri = const_cast<int&>(i); // is that UB?
}

int main()
{
foo(42);
int a = 42;
foo(a);
}

A literal is not a run-time object, of course. It's an element of the
program (before it's compiled and run).

Inside 'foo' the code doesn't really know what 'i' represents. It's
bound to something. To what? Why should the code care?

That's what I thought siddhu was asking about.
What "const" means is that the stored value of an object does not change
from one to another value. Changing the object may change the stored value
to something else. "const" prevents such changes to the object.

'const' is a keyword. It means different things in different contexts.
A value in and of itself does not convey a meaning of "const". Hence, in
C++, non-class and non-array rvalues cannot be const qualified. That makes a
great deal of sense, because they are not objects.

It should be mentioned that the C++ Standard does not know a strict
distinction between "value" and "object". In my text above, I used "value"
in the sense of "the abstract meaning designated by an object's value
representation", as defined by 3.9p4 (sadly that definition of "value" isn't
used consistently throughout the spec or draft).

V
 
B

Balog Pal

Victor Bazarov said:
Any data initializing which requires code to be executed at runtime cannot
be put in "the 'const' segment" - the segment would not be const, would
it?

Why should it be initialized "at runtime"? Unless you have volatiles
involved, what is pretty rare, the standard mandates that initialisation
happened before you use. Not telling how much before. It can be done at
compile time, if the compiler can guess the result. Like in the above case.

Or how would you tell the difference from within a program?
 
I

Ian Collins

Why should it be initialized "at runtime"? Unless you have volatiles
involved, what is pretty rare, the standard mandates that initialisation
happened before you use. Not telling how much before. It can be done at
compile time, if the compiler can guess the result. Like in the above case.

Maybe it could, but do you know a case where it is? The two compilers I
tried (Sun CC and g++) build the object in a static constructor.

Oh the joys of UB....
 
I

Ian Collins

In principle the program can perform the dynamic initialisation of const
objects at startup, then mark the relevant VM pages as read-only. I guess
no implementation bothers to do such things currently.

The most imminent danger with changing const objects is that the compiler
is allowed to optimize away repeated reads of the data even if it cannot
prove the data is not modified meanwhile. This might lead to subtle bugs,
appearing probably only in optimized compilations. So even if the class
object is not "truly const", it might effectively act as such.

A really simple example is:

void g( int );

int main()
{
const int n = 42;
int* p = const_cast<int*>(&n);
*p = 43;
g(n);
g(*p);
}
 
B

Balog Pal

Ian Collins said:
Maybe it could, but do you know a case where it is? The two compilers I
tried (Sun CC and g++) build the object in a static constructor.

For the pair above VS2008 create the bytes directly with their values.
But initialised data appears to go in the _TEXT segment now...

So the optimisation I suggested actually happens.
 
B

Bo Persson

Victor said:
I see two concepts here, removing of 'const' and changing. I don't
think that the former is the same as the latter, or is it?

V

Right, casting away const as such is ok, as long as you don't use it
for anything non-const.

My point was more that class objects can very well be read-only.
Trying to change them will then have an undefined result.



Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top