View mode: basic / threaded / horizontal-split · Log in · Help
June 18, 2007
D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Re: D2.0: an example of use-case for casting invariant away
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
Top | Discussion index | About this forum | D home