Jump to page: 1 24  
Page
Thread overview
Casting away const
Aug 08, 2010
simendsjo
Aug 08, 2010
bearophile
Aug 08, 2010
div0
Aug 08, 2010
BCS
Aug 09, 2010
bearophile
Aug 09, 2010
Don
Aug 09, 2010
Simen kjaeraas
Aug 09, 2010
Simen kjaeraas
Aug 09, 2010
Simen kjaeraas
Aug 09, 2010
BCS
Aug 09, 2010
Jonathan M Davis
Aug 09, 2010
Jonathan M Davis
Aug 09, 2010
Don
Aug 09, 2010
BCS
Aug 09, 2010
BCS
Aug 09, 2010
BCS
Aug 09, 2010
bearophile
Aug 09, 2010
bearophile
Aug 09, 2010
Mafi
Aug 09, 2010
bearophile
Aug 09, 2010
Lutger
Aug 09, 2010
Lutger
Aug 09, 2010
BCS
Aug 09, 2010
BCS
August 08, 2010
I'm totally new to the const/immutable thing, so this might be a naive question..

The spec says:
"modification after casting away const" => "undefined behavior"

// ptr to const int
const(int)* p;
int* q = cast(int*)p;
*q = 3;   // undefined behavior

But why would you want to cast away const then? If it's for passing to a function that doesn't take const, you're just shooting yourself in the foot by giving it illegal data to work with.

This little test works:
unittest
{
	const int i = 10;
	const(int)* p = &i;
	assert(*p == 10);
	assert(p == &i);
	
	int* q = cast(int*)p;
	assert(q == &i);
	assert(*q == 10);
	
	*q = 1; // spec says undefined behavior
	assert(*q == 1); // but the value is changed
	assert(*p == 1); // but p is also changed
	
	assert(p == q); // still same reference.
	assert(q == &i);
	assert(p == &i);
	assert(i == 10); // i still 10 though.. How is this possible?
}
August 08, 2010
simendsjo:
> But why would you want to cast away const then?

I presume for a situation where you are sure your code is just reading the information and not modifying it, and you need something that is not const.


> 	assert(i == 10); // i still 10 though.. How is this possible?

You have done something that you are not supposed to do. Undefined behaviour means that it generally produces unexpected effects/results :-)

Bye,
bearophile
August 08, 2010
On 08/08/2010 22:56, simendsjo wrote:
> I'm totally new to the const/immutable thing, so this might be a naive
> question..
>
> The spec says:
> "modification after casting away const" => "undefined behavior"

Casting away const is mostly for dealing with external non D libraries.
Some languages have no notion of const, so you'll cast const away when calling functions written in other languages.

Also a lot of old c & c++ code is none const correct so again you have to discard const to interface with that code.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
August 08, 2010
Hello simendsjo,

> I'm totally new to the const/immutable thing, so this might be a naive
> question..
> 
> The spec says:
> "modification after casting away const" => "undefined behavior"
> // ptr to const int
> const(int)* p;
> int* q = cast(int*)p;
> *q = 3;   // undefined behavior
> But why would you want to cast away const then? If it's for passing to
> a function that doesn't take const, you're just shooting yourself in
> the foot by giving it illegal data to work with.
> 
> This little test works:
> unittest
> {
> const int i = 10;
> const(int)* p = &i;
> assert(*p == 10);
> assert(p == &i);
> int* q = cast(int*)p;
> assert(q == &i);
> assert(*q == 10);
> *q = 1; // spec says undefined behavior

Your code at this point can do anything

> assert(*q == 1); // but the value is changed
> assert(*p == 1); // but p is also changed
> assert(p == q); // still same reference.
> assert(q == &i);
> assert(p == &i);
> assert(i == 10); // i still 10 though.. How is this possible?
> }

Because i is const int and initialized with a constant, the compiler is free to do things replace instances of i with the value rather than loading the value from ram. Allowing that sort of things is the reason for const and the undefined behavior bit is to prevent the compiler from needing to check for what you did.

Off hand, other ways that your example could fail include:
-the compiler putting i in a global variable (if this were in a recursive function...)
-combining it with other global consts, or even code, that happen to have the same bit pattern as 10 (at which point you just messed up code that uses them)
-putting it in a read only memory segment (and then "*q = 1" will seg-v)

-- 
... <IXOYE><



August 09, 2010
On Sun, 08 Aug 2010 17:56:25 -0400, simendsjo <simen.endsjo@pandavre.com> wrote:

> I'm totally new to the const/immutable thing, so this might be a naive question..
>
> The spec says:
> "modification after casting away const" => "undefined behavior"

I thought it was "you're on your own", not undefined behavior.  The former implies there is some "right" way to do this if you know more about the data than the compiler, the latter implies that there is no right way to cast away const.  Am I wrong?

-Steve
August 09, 2010
Steven Schveighoffer:
> I thought it was "you're on your own", not undefined behavior.  The former implies there is some "right" way to do this if you know more about the data than the compiler, the latter implies that there is no right way to cast away const.  Am I wrong?

In my opinion if this thing is well designed then you go in undefined behaviour only when you change the contents of something after you have removed its const nature with a cast. Just casting const away and then reading the data can't be undefined behaviour, otherwise casting const away is useless and can be totally disallowed.

Bye,
bearophile
August 09, 2010
Steven Schveighoffer wrote:
> On Sun, 08 Aug 2010 17:56:25 -0400, simendsjo <simen.endsjo@pandavre.com> wrote:
> 
>> I'm totally new to the const/immutable thing, so this might be a naive question..
>>
>> The spec says:
>> "modification after casting away const" => "undefined behavior"
> 
> I thought it was "you're on your own", not undefined behavior.  The former implies there is some "right" way to do this if you know more about the data than the compiler, the latter implies that there is no right way to cast away const.  Am I wrong?
> 
> -Steve

I think you're wrong. It's OK to cast away const, as long as you don't modify the thing which is supposed to be const.
But if you modify it, there's no way the compiler can guarantee that your code will work. Anything could happen.
August 09, 2010
On Mon, 09 Aug 2010 09:57:47 -0400, bearophile <bearophileHUGS@lycos.com> wrote:

> Steven Schveighoffer:
>> I thought it was "you're on your own", not undefined behavior.  The former
>> implies there is some "right" way to do this if you know more about the
>> data than the compiler, the latter implies that there is no right way to
>> cast away const.  Am I wrong?
>
> In my opinion if this thing is well designed then you go in undefined behaviour only when you change the contents of something after you have removed its const nature with a cast. Just casting const away and then reading the data can't be undefined behaviour, otherwise casting const away is useless and can be totally disallowed.

Casting away const just to read the data is useless.  You can read const data without a cast.

But my understanding is that casting away const to write should be doable if you know what you're doing.  If this is undefined behavior, then that's fine, I'm just unclear on what "undefined behavior" actually means.  I thought "undefined behavior" means that you cannot count on the behavior to work in the future.

An example of where casting away const to write should be allowed is for a hypothetical mutable member:

class C
{
   private Mutable!(int) cache = -1;
   int expensiveFunction() const { return cache == -1 ? cache = _expensiveFunctionImpl() : cache; }
   private int _expensiveFunctionImpl() const {...}
}

If this is undefined, then something like this cannot be relied on, even when performance is critical.

-Steve
August 09, 2010
On Mon, 09 Aug 2010 10:11:39 -0400, Don <nospam@nospam.com> wrote:

> Steven Schveighoffer wrote:
>> On Sun, 08 Aug 2010 17:56:25 -0400, simendsjo <simen.endsjo@pandavre.com> wrote:
>>
>>> I'm totally new to the const/immutable thing, so this might be a naive question..
>>>
>>> The spec says:
>>> "modification after casting away const" => "undefined behavior"
>>  I thought it was "you're on your own", not undefined behavior.  The former implies there is some "right" way to do this if you know more about the data than the compiler, the latter implies that there is no right way to cast away const.  Am I wrong?
>>  -Steve
>
> I think you're wrong. It's OK to cast away const, as long as you don't modify the thing which is supposed to be const.
> But if you modify it, there's no way the compiler can guarantee that your code will work. Anything could happen.

But then what is the point of casting away const?  If you are not going to modify it, then there is no reason to cast it away.

What about how Rebindable works?  It doesn't exactly cast away const, it uses a union, but the effect is the same.  Is this OK simply because a union is used?

Also, see my reply to bearophile, with hypothetical example.

-Steve
August 09, 2010
Hello Steven,

> On Sun, 08 Aug 2010 17:56:25 -0400, simendsjo
> <simen.endsjo@pandavre.com>  wrote:
> 
>> I'm totally new to the const/immutable thing, so this might be a
>> naive  question..
>> 
>> The spec says:
>> "modification after casting away const" => "undefined behavior"
> I thought it was "you're on your own", not undefined behavior.  The
> former  implies there is some "right" way to do this if you know more
> about the  data than the compiler, the latter implies that there is no
> right way to  cast away const.  Am I wrong?

I think you are right re the meaning of those terms but I think what you thought it to be is more along the lines of what is correct. I /think/ the situation is that there are things that will work reliably and things that result in undefined behavior and you're on your own figuring out what is what.

> -Steve
> 
-- 
... <IXOYE><



« First   ‹ Prev
1 2 3 4