Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > A cast question

Reply
Thread Tools

A cast question

 
 
Jack
Guest
Posts: n/a
 
      12-10-2012
In the following code (taken from a book):

struct Class {
size_t size;
void * (* ctor) (void * self, va_list * app);
void * (* dtor) (void * self);
void * (* clone) (const void * self);
int (* differ) (const void * self, const void * b);
};

void * new (const void * _class, ...)
{
const struct Class * class = _class;
void * p = calloc(1, class —> size);

* (const struct Class **) p = class; //LINE1
if (class —> ctor)
{ va_list ap;
va_start(ap, _class);
p = class —> ctor(p, & ap);
va_end(ap);
}
return p;
}

At LINE1, why cast P to (const struct Class **) first, then deference it?
Is not LINE1 equal to the following line?

(const struct Class *) p = class;


Thanks.

Jack
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      12-10-2012
Jack wrote:
> In the following code (taken from a book):
>
> struct Class {
> size_t size;
> void * (* ctor) (void * self, va_list * app);
> void * (* dtor) (void * self);
> void * (* clone) (const void * self);
> int (* differ) (const void * self, const void * b);
> };
>
> void * new (const void * _class, ...)
> {
> const struct Class * class = _class;
> void * p = calloc(1, class —> size);
>
> * (const struct Class **) p = class; //LINE1
> if (class —> ctor)
> { va_list ap;
> va_start(ap, _class);
> p = class —> ctor(p, & ap);
> va_end(ap);
> }
> return p;
> }
>
> At LINE1, why cast P to (const struct Class **) first, then deference it?
> Is not LINE1 equal to the following line?
>
> (const struct Class *) p = class;


No, the above isn't valid syntax (see the earlier "Casts on lvalues"
thread for the gore). Even if it were valid, it would change the value
of p rather than saving the value of class in the memory pointed to by p.

They could have written

const struct Class** p = calloc( 1, class->size );

*p = class;

--
Ian Collins
 
Reply With Quote
 
 
 
 
Prathamesh Kulkarni
Guest
Posts: n/a
 
      12-10-2012
On Monday, 10 December 2012 02:30:43 UTC-5, Jack wrote:
> In the following code (taken from a book):
>
>
>
> struct Class {
>
> size_t size;
>
> void * (* ctor) (void * self, va_list * app);
>
> void * (* dtor) (void * self);
>
> void * (* clone) (const void * self);
>
> int (* differ) (const void * self, const void * b);
>
> };
>
>
>
> void * new (const void * _class, ...)
>
> {
>
> const struct Class * class = _class;
>
> void * p = calloc(1, class —> size);
>
>
>
> * (const struct Class **) p = class; //LINE1


If you intend to use p as pointer to pointer to
struct Class, shouldn't it be
void *p = calloc(1, sizeof(struct Class *)); ?

>
> if (class —> ctor)
>
> { va_list ap;
>
> va_start(ap, _class);
>
> p = class —> ctor(p, & ap);
>
> va_end(ap);
>
> }
>
> return p;
>
> }
>
>
>
> At LINE1, why cast P to (const struct Class **) first, then deference it?
>
> Is not LINE1 equal to the following line?
>
>
>
> (const struct Class *) p = class;
>
>
>
>
>
> Thanks.
>
>
>
> Jack


 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-10-2012
Jack <> writes:

> In the following code (taken from a book):
>
> struct Class {
> size_t size;
> void * (* ctor) (void * self, va_list * app);
> void * (* dtor) (void * self);
> void * (* clone) (const void * self);
> int (* differ) (const void * self, const void * b);
> };
>
> void * new (const void * _class, ...)
> {
> const struct Class * class = _class;
> void * p = calloc(1, class —> size);
>
> * (const struct Class **) p = class; //LINE1
> if (class —> ctor)
> { va_list ap;
> va_start(ap, _class);
> p = class —> ctor(p, & ap);
> va_end(ap);
> }
> return p;
> }
>
> At LINE1, why cast P to (const struct Class **) first, then deference it?
> Is not LINE1 equal to the following line?
>
> (const struct Class *) p = class;


As has been said, no. You can't assign to a cast expression.

But this code is pretty gruesome! It would be much clearer if the
intent were made plain. The idea is that every class instance starts
with a pointer to a struct describing the class. There is no need to
lie about that -- you can "over allocate" perfectly legally, so the
author could have written:

struct ClassInstance {
struct Class *class;
};

and in new:

const struct Class *class = _class;
struct ClassInstance *inst = calloc(1, class->size);
inst->class = class;
if (class->ctor)
{ va_list ap;
va_start(ap, _class);
inst = class->ctor(inst, &ap);
va_end(ap);
}
return inst;

(and I'd change the return type, too).

Depending on the rest of the code, it's possible that the lie (called
type punning) might even break on some odd architectures.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is the result of valid dynamic cast always equal to the result ofcorrespondent static cast? Pavel C++ 7 09-18-2010 11:35 PM
error C2440: 'return' : cannot convert from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Abhijit Bhadra C++ 2 12-01-2004 04:43 PM
malloc - to cast or not to cast, that is the question... EvilRix C Programming 8 02-14-2004 12:08 PM
to cast or not to cast malloc ? MSG C Programming 38 02-10-2004 03:13 PM
Question: Invalid Cast Exception Error VB Programmer ASP .Net 4 10-28-2003 03:13 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57