Pointer casts for OOP

S

Sean Hamilton

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,
 
M

Malcolm McLean

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.
 
J

James Kuyper

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top