Jump to page: 1 24  
Page
Thread overview
D2.0: an example of use-case for casting invariant away
Jun 18, 2007
eao197
Jun 18, 2007
Brad Roberts
Jun 18, 2007
Walter Bright
Jun 18, 2007
Sean Kelly
Jun 18, 2007
Daniel Keep
Jun 18, 2007
Walter Bright
Jun 19, 2007
James Dennett
Jun 19, 2007
Walter Bright
Jun 21, 2007
Don Clugston
Jun 21, 2007
Walter Bright
Jun 21, 2007
Don Clugston
Casts
Jun 21, 2007
Oskar Linde
Jun 21, 2007
Walter Bright
Jun 21, 2007
eao197
Jun 21, 2007
Regan Heath
Jun 21, 2007
Don Clugston
Jun 21, 2007
Oskar Linde
Jun 21, 2007
Eugene Pelekhay
Jun 21, 2007
Daniel Keep
Jun 21, 2007
Tom S
Jun 22, 2007
Bruno Medeiros
Jun 22, 2007
Bruno Medeiros
Jun 23, 2007
Don Clugston
Jun 23, 2007
Bruno Medeiros
Jun 24, 2007
Daniel Keep
Jun 25, 2007
Bruno Medeiros
Jun 25, 2007
BCS
Jun 24, 2007
Anders Bergh
Jun 24, 2007
Jason House
Jun 24, 2007
James Dennett
Jun 24, 2007
Jason House
Jun 25, 2007
James Dennett
Jun 25, 2007
Don Clugston
Jun 24, 2007
Carlos Santander
Jun 25, 2007
torhu
Jun 21, 2007
Jascha Wetzel
Jun 18, 2007
Daniel Keep
June 18, 2007
	Hello!

It is a question only for clarification for myself. If I understand http://www.digitalmars.com/d/final-const-invariant.html correctly the casting invariant away allowed for situations like this:

// An interface for some third-party library
// (which is probably written in some exotic language).
extern(C) void initSomeSubsystem( char * initializationString );
...
// Our D2.0 stuff.
int main()
  {
    invariant char* initializationString = "...";
    // Casting invariant away is necessary here.
    initSomeSubsystem( cast(invariant) initializationString );
  }

Am I correct?

-- 
Regards,
Yauheni Akhotnikau
June 18, 2007
eao197 wrote:
>     Hello!
> 
> It is a question only for clarification for myself. If I understand http://www.digitalmars.com/d/final-const-invariant.html correctly the casting invariant away allowed for situations like this:
> 
> // An interface for some third-party library
> // (which is probably written in some exotic language).
> extern(C) void initSomeSubsystem( char * initializationString );
> ...
> // Our D2.0 stuff.
> int main()
>   {
>     invariant char* initializationString = "...";
>     // Casting invariant away is necessary here.
>     initSomeSubsystem( cast(invariant) initializationString );
>   }
> 
> Am I correct?
> 
> --Regards,
> Yauheni Akhotnikau

First, is the library actually treating the initString as read only?  If it's not, then you shouldn't pass an invariant (or const) string down to it.  The results would be undefined.

If it's actually treating the string as read-only, then I'd be tempted to change the extern(c) declaration to pass the argument as const char * rather than casting away the invariantness.  Note, I haven't tried this, just an off the top of my head suggestion.

Later,
Brad
June 18, 2007
In addition to Brad's response, note that this is *not* "casting invariant away".  You are *adding* invariant[1].  This might be more accurate:

extern(C) void initSomeSubsystem(char * initializationString);

int main()
{
    invariant char * initString = "...";
    // Cast away invariantness of initString so we can pass it to the C
    // function; be it on your head if the function tries to change it!
    initSomeSubsystem( cast(char*)initString );
}

	-- Daniel

[1] Although it's already there, so it wouldn't have any effect, I don't think.
June 18, 2007
Brad Roberts wrote:
> If it's actually treating the string as read-only, then I'd be tempted to change the extern(c) declaration to pass the argument as const char * rather than casting away the invariantness.

The need to be able to cast away const-ness is to interface to libraries that you cannot go and change.

Also, the type system is not meant to be a straitjacket. If you absolutely must do something, and you know what you are doing, there should be a way to do it.
June 18, 2007
Walter Bright wrote:
> Brad Roberts wrote:
>> If it's actually treating the string as read-only, then I'd be tempted to change the extern(c) declaration to pass the argument as const char * rather than casting away the invariantness.
> 
> The need to be able to cast away const-ness is to interface to libraries that you cannot go and change.
> 
> Also, the type system is not meant to be a straitjacket. If you absolutely must do something, and you know what you are doing, there should be a way to do it.

That's understandable, but isn't it contrary to your statement that const in C++ is useless because of const_cast?  Or is it the presence of a cast specifically intended to cast away const that you take issue with?


Sean
June 18, 2007

Sean Kelly wrote:
> Walter Bright wrote:
>> Brad Roberts wrote:
>>> If it's actually treating the string as read-only, then I'd be tempted to change the extern(c) declaration to pass the argument as const char * rather than casting away the invariantness.
>>
>> The need to be able to cast away const-ness is to interface to libraries that you cannot go and change.
>>
>> Also, the type system is not meant to be a straitjacket. If you absolutely must do something, and you know what you are doing, there should be a way to do it.
> 
> That's understandable, but isn't it contrary to your statement that const in C++ is useless because of const_cast?  Or is it the presence of a cast specifically intended to cast away const that you take issue with?
> 
> 
> Sean

Walter's said on a few occasions that the problem with C++'s const is that casting away const is a *well-defined* operation.  That means that const cannot be used to do any kind of optimisation, since it doesn't really mean anything.

The new page on const specifically states that casting away const or invariance is *not* a well-defined operation, and you'd better know what you're doing when you do it.

	-- Daniel
June 18, 2007
Daniel Keep wrote:
> Walter's said on a few occasions that the problem with C++'s const is
> that casting away const is a *well-defined* operation.  That means that
> const cannot be used to do any kind of optimisation, since it doesn't
> really mean anything.
> 
> The new page on const specifically states that casting away const or
> invariance is *not* a well-defined operation, and you'd better know what
> you're doing when you do it.

More specifically, in C++, you can cast away const-ness and then modify the underlying data, and this is defined to be legal, defined behavior.

With D, you can cast away const-ness, that is legal. But if you subsequently modify the underlying data, that is undefined behavior.
June 19, 2007
Walter Bright wrote:
> Daniel Keep wrote:
>> Walter's said on a few occasions that the problem with C++'s const is that casting away const is a *well-defined* operation.  That means that const cannot be used to do any kind of optimisation, since it doesn't really mean anything.
>>
>> The new page on const specifically states that casting away const or invariance is *not* a well-defined operation, and you'd better know what you're doing when you do it.
> 
> More specifically, in C++, you can cast away const-ness and then modify the underlying data, and this is defined to be legal, defined behavior.

More specifically still, in C++ you can cast away const-ness and then
modify the underlying object only if that underlying object is not
defined as being const.  If you modify an object that is actually
const (where I think Walter might say that it has const as it
"storage class", though that doesn't match C++ terminology) then
you have undefined behavior.

> With D, you can cast away const-ness, that is legal. But if you subsequently modify the underlying data, that is undefined behavior.

Seems reasonable to me (though one of C++'s faults is that it has
*too much* undefined behavior).

-- James
June 19, 2007
James Dennett wrote:
> Seems reasonable to me (though one of C++'s faults is that it has
> *too much* undefined behavior).

C++ has too much implementation defined and undefined behavior. D has less, but it should be even less.

ID and UB impede source portability.
June 21, 2007
Walter Bright wrote:
> Daniel Keep wrote:
>> Walter's said on a few occasions that the problem with C++'s const is
>> that casting away const is a *well-defined* operation.  That means that
>> const cannot be used to do any kind of optimisation, since it doesn't
>> really mean anything.
>>
>> The new page on const specifically states that casting away const or
>> invariance is *not* a well-defined operation, and you'd better know what
>> you're doing when you do it.
> 
> More specifically, in C++, you can cast away const-ness and then modify the underlying data, and this is defined to be legal, defined behavior.
> 
> With D, you can cast away const-ness, that is legal. But if you subsequently modify the underlying data, that is undefined behavior.

It sounds that in D, it will be too easy to cast away constness accidentally.
With C++, at least you can grep for const_cast and detect potentially dangerous code, and you get a strong visual clue.
Suppose I've written a D function like this:

void f(int *b, uint c)
{
  // maybe I'm avoiding a compiler warning or something.
  uint *d = cast(uint *)b;
  d += c;
}

Months later, I'm refactoring the code, and I convert the int * parameter to an invariant, without recognising that it's changing the value of b. Oops.

C++'s const would catch this mistake, but if I understand correctly, D will compile it without error. Suddenly the function has moved into the realm of undefined behaviour.

I hope I'm wrong. Or did I miss something?
« First   ‹ Prev
1 2 3 4