[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Pointer casts for OOP

Sean Hamilton

8/18/2011 12:54:00 PM

Hello,

struct super { int i; };
struct sub { struct super super; int j; };

Is it safe to cast a (struct sub *) to a (struct super *) to access i,
while using the original (struct sub *) to access j? Since i and j do
not overlap, there should be no pointer aliasing issues, correct? I'm
more concerned about the pointer cast being undefined -- it works with
gcc of course, but I suspect this is not guaranteed.

Also what about covariance and contravariance of function pointers
which accept and return these pointer types? Are these casts
guaranteed to work? For example, if I have void f (struct super * s),
can I assign this to a void (*) (struct sub *), and safely call this
function pointer with a (struct sub *)? Of course the goal here is to
implement virtual functions. Again it works in gcc, but I'm not sure I
can depend on it.

Getting OT, does gcc make some kind of promise that pointer casts like
this will work, beyond the C standard, or is this some terrible bug
just waiting to emerge? I've noticed this seems pretty widespread in
general, for example the BSD sockets API.

Is there a standard and well-behaved way to do all this, perhaps with
macros? If it's unsafe/undefined, can it be made safe with strategic
casts to (void *)? I've noticed some quick guides to OOP patterns in
C, but they seem to ignore these issues. Should I just use that other
language?

Thanks in advance,
2 Answers

Malcolm McLean

8/18/2011 2:11:00 PM

0

On Aug 18, 3:53 pm, Sean Hamilton <seanhamil...@gmail.com> wrote:
> Hello,
>
> struct super { int i; };
> struct sub { struct super super; int j; };
>
> Is it safe to cast a (struct sub *) to a (struct super *) to access i,
> while using the original (struct sub *) to access j? Since i and j do
> not overlap, there should be no pointer aliasing issues, correct?
>
C guarantees that the first member of a struct will be first in
memory, and have the same address as the struct itself. Pointers in C
are allowed to alias.

You're storing up problems for the future because the pointer aliasing
problem is a very difficult one for optimisers to solve. However few
programs fail because this sort of micro-optimisation isn't efficient
enugh.
--
Malcolm's website
http://www.malcolmmclean.site...


James Kuyper

8/18/2011 2:17:00 PM

0

On 08/18/2011 08:53 AM, Sean Hamilton wrote:
> Hello,
>
> struct super { int i; };
> struct sub { struct super super; int j; };
>
> Is it safe to cast a (struct sub *) to a (struct super *) to access i,
> while using the original (struct sub *) to access j?

Conversion of a pointer to a struct into a pointer to the type of the
first member of that struct is safe and guaranteed to give what you
want. Given:

struct sub *sandwich;

Then you are guaranteed that:

(struct super*)sandwich == &sandwich->super

However, I'd recommend using &sandwich->super. It's not only clearer,
but it will continue to do precisely what needs to be done, even if
someone later decides to insert something before 'super' in struct sub.

> Also what about covariance and contravariance of function pointers
> which accept and return these pointer types? Are these casts
> guaranteed to work? For example, if I have void f (struct super * s),
> can I assign this to a void (*) (struct sub *), and safely call this
> function pointer with a (struct sub *)?

The reverse conversion is also guaranteed to work.

> Getting OT, does gcc make some kind of promise that pointer casts like
> this will work, beyond the C standard,

I've no idea whether gcc guarantees that this works in it's default
mode, where it implements GNU C, not standard C. However, the C standard
does guarantee this, and if you use -ansi, -std=c90 or -std=c99, gcc
will do the same.
--
James Kuyper