www.digitalmars.com         C & C++   DMDScript  

D - typecasts (again) a cast with 2 params

reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
having just run fowl a simple missing &, I wondered what the responce to
allowing a typecast to not take one type as a param but two
so instead of (or as well as)  `cast( type )var;` there would be a `cast(
to-type, from-type) var;`
so that any changes in var would be reflected by an error.
for instance
uint stuff[] = new uint[4];
...
void * foo = cast(void *)(&(stuff[1])); // fine but there are times when you
want this.
however
void * foo = cast(void *)(stuff[1]); // rather different and may not be what
was required;

these would become
void * foo = cast(void *, uint*)(&(stuff[1])); // fine but there are times
when you want this.
however
void * foo = cast(void *, uint)(stuff[1]); // I really mean cast uint
element 1 to a void *
if, by mistake you wrote
void * foo = cast(void *, uint*)(stuff[1]);
then the compiler could warn you that the rhs was of the incorrect type.
uint not uint*

my reasoning is this, with one hand D offers GC which make robust OO
programming a little easier, and allows much simpler exception as each
unwound method frame does not now require cleaning up as much (the gc does
it later, only auto's need explicit cleanup to be added by the compiler).
then on the other the single 'C' cast (even if not 'C' style) allows,
without warning anything to be transmuted into anything else.
I would like to see the 'C' cast only allow for "safe" casts
numerics <-> numeric, or pointer<->pointer but not numeric<->pointer.
pointers to struct should be treated like objects 'C' casts; only allowed if
they inherit (or in the case of a struct, a pointer to the first member).
otherwise a two type cast is required. informing yourself, other programmers
and the compiler that you do know what you are doing.

Mike.
Feb 05 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b1s5ev$mg9$1 digitaldaemon.com...
 my reasoning is this, with one hand D offers GC which make robust OO
 programming a little easier, and allows much simpler exception as each
 unwound method frame does not now require cleaning up as much (the gc does
 it later, only auto's need explicit cleanup to be added by the compiler).
 then on the other the single 'C' cast (even if not 'C' style) allows,
 without warning anything to be transmuted into anything else.
 I would like to see the 'C' cast only allow for "safe" casts
 numerics <-> numeric, or pointer<->pointer but not numeric<->pointer.
 pointers to struct should be treated like objects 'C' casts; only allowed
if
 they inherit (or in the case of a struct, a pointer to the first member).
 otherwise a two type cast is required. informing yourself, other
programmers
 and the compiler that you do know what you are doing.
I understand your reasoning. D has a number of features to reduce the need for casting in ordinary programming, but they'll always be needed as an escape from the typing system. But, of course, escaping from the type system means you're on your own. I think your idea has merit, but it doesn't address the common casting problem of getting the wrong number of *'s when converting pointer types, etc.
Mar 06 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b495tq$16l3$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b1s5ev$mg9$1 digitaldaemon.com...
 my reasoning is this, with one hand D offers GC which make robust OO
 programming a little easier, and allows much simpler exception as each
 unwound method frame does not now require cleaning up as much (the gc
does
 it later, only auto's need explicit cleanup to be added by the
compiler).
 then on the other the single 'C' cast (even if not 'C' style) allows,
 without warning anything to be transmuted into anything else.
 I would like to see the 'C' cast only allow for "safe" casts
 numerics <-> numeric, or pointer<->pointer but not numeric<->pointer.
 pointers to struct should be treated like objects 'C' casts; only
allowed
 if
 they inherit (or in the case of a struct, a pointer to the first
member).
 otherwise a two type cast is required. informing yourself, other
programmers
 and the compiler that you do know what you are doing.
I understand your reasoning. D has a number of features to reduce the need for casting in ordinary programming, but they'll always be needed as an escape from the typing system. But, of course, escaping from the type
system
 means you're on your own. I think your idea has merit, but it doesn't
 address the common casting problem of getting the wrong number of *'s when
 converting pointer types, etc.
in what way does it not solve the wrong *'s problem nothing is going to stop what should be int foo( void * param ) { bar ** ptr = cast(bar**)param; } being written as int foo( void * param ) { bar * ptr = cast(bar*)param; } but will stop int foo( int ** param ) { bar ** ptr = cast(bar**)(*param); } for being written as int foo( int ** param ) { bar ** ptr = cast(bar**)param; } int foo( int ** param ) { bar ** ptr = cast(int* to bar**)(*param); // valid } int foo( int ** param ) { bar ** ptr = cast(int* to bar**)(param); // not valid param is not an int* } int foo( int param ) { bar ** ptr = cast(int* to bar**)(param); // invalid param is not int* } int foo( int param ) { bar ** ptr = cast(int* to bar**)(&param); // valid }
Mar 07 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b49ljo$1g27$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:b495tq$16l3$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b1s5ev$mg9$1 digitaldaemon.com...
 my reasoning is this, with one hand D offers GC which make robust OO
 programming a little easier, and allows much simpler exception as each
 unwound method frame does not now require cleaning up as much (the gc
does
 it later, only auto's need explicit cleanup to be added by the
compiler).
 then on the other the single 'C' cast (even if not 'C' style) allows,
 without warning anything to be transmuted into anything else.
 I would like to see the 'C' cast only allow for "safe" casts
 numerics <-> numeric, or pointer<->pointer but not numeric<->pointer.
 pointers to struct should be treated like objects 'C' casts; only
allowed
 if
 they inherit (or in the case of a struct, a pointer to the first
member).
 otherwise a two type cast is required. informing yourself, other
programmers
 and the compiler that you do know what you are doing.
I understand your reasoning. D has a number of features to reduce the
need
 for casting in ordinary programming, but they'll always be needed as an
 escape from the typing system. But, of course, escaping from the type
system
 means you're on your own. I think your idea has merit, but it doesn't
 address the common casting problem of getting the wrong number of *'s
when
 converting pointer types, etc.
in what way does it not solve the wrong *'s problem nothing is going to stop what should be int foo( void * param ) { bar ** ptr = cast(bar**)param; } being written as int foo( void * param ) { bar * ptr = cast(bar*)param; } but will stop int foo( int ** param ) { bar ** ptr = cast(bar**)(*param); } for being written as int foo( int ** param ) { bar ** ptr = cast(bar**)param; } int foo( int ** param ) { bar ** ptr = cast(int* to bar**)(*param); // valid } int foo( int ** param ) { bar ** ptr = cast(int* to bar**)(param); // not valid param is not an int* } int foo( int param ) { bar ** ptr = cast(int* to bar**)(param); // invalid param is not int* } int foo( int param ) { bar ** ptr = cast(int* to bar**)(&param); // valid }
It does add some redundancy which will reduce some bugs, as you illustrated. But when *** is cast to ** instead of *, it isn't caught.
Mar 11 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:

 in what way does it not solve the wrong *'s problem

 nothing is going to stop what should be
 int foo( void * param ) {
     bar ** ptr = cast(bar**)param;
 }
 being written as
 int foo( void * param ) {
     bar * ptr = cast(bar*)param;
 }

 but will stop
 int foo( int ** param ) {
     bar ** ptr = cast(bar**)(*param);
 }
 for being written as
 int foo( int ** param ) {
     bar ** ptr = cast(bar**)param;
 }

 int foo( int ** param ) {
     bar ** ptr = cast(int* to bar**)(*param);  // valid
 }

 int foo( int ** param ) {
     bar ** ptr = cast(int* to bar**)(param); // not valid param is not
an
 int*
 }

 int foo( int  param ) {
     bar ** ptr = cast(int* to bar**)(param);  // invalid param is not
int*
 }

 int foo( int param ) {
     bar ** ptr = cast(int* to bar**)(&param); // valid
 }
It does add some redundancy which will reduce some bugs, as you
illustrated.
 But when *** is cast to ** instead of *, it isn't caught.
if you write func ( bar *** param ) { bar ** pp = cast( bar *** to bar ** )param; ..... } instead of func ( bar *** param ) { bar * pp = cast( bar *** to bar * )param; ..... } nothing will every catch that error I accept that, but what it does catch is changes in params/members and missing '&' and *'s (no matter how many &*'s are involved as long as you've got the right types in the cast expr) and especially when passing params as void * to c, where you know what you want you can write func ( bar ** foo ) { void * pp = cast( bar *** to void * )&param; // has to have the & or its an error ..... } which will catch the missing & or * [void * pp = cast( bar* to void*)*param;] {&param or param would cause error} or course you need to get the from type correct but as it stands void * pp = cast(void*)*bar; void * pp = cast(void*)bar; void * pp = cast(void*)&bar; are all valid and might be correct there is no way to get the compiler to check you've got the right number of &,* 's for what you think should be passed (be it Bar ******* or Bar*) if this is not what you mean by 'But when *** is cast to ** instead of *, it isn't caught.' can you post an example please.
Mar 11 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b4lnf4$cik$1 digitaldaemon.com...
 if this is not what you mean by 'But when *** is cast to ** instead of *,
it
 isn't caught.'
It is what I meant, you have it right.
Mar 11 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b4loik$d8q$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b4lnf4$cik$1 digitaldaemon.com...
 if this is not what you mean by 'But when *** is cast to ** instead of
*,
 it
 isn't caught.'
It is what I meant, you have it right.
so am I right in assuming you do not see enough merit in having a two param typecast, because the programmer can inform the cast to perform the wrong action. I (obviously) think its a step in the right direction and I can work around it with a templated cast func (although template syntax is rather verbose) or a nexted func to do the lhs typecheck.
Mar 11 2003
parent "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b4lrq6$lse$1 digitaldaemon.com...
 so am I right in assuming you do not see enough merit in having a two
param
 typecast, because the programmer can inform the cast to perform the wrong
 action.
Yes.
 I (obviously) think its a step in the right direction and I can work
around
 it with a templated cast func (although template syntax is rather verbose)
 or a nexted func to do the lhs typecheck.
Apr 04 2003