Circumventing the -fno-strict-aliasing switch

S

Shao Miller

Moreover, I just want people to be able add arbitrary 'primitive'
types which means they should also be able to store anything in a
terminal node. I.e., I envision that people will want to store
arbitrary structures into them. Like a tuple of doubles for OpenGL, or
a tuple of characters for an environment hashmap, or whatever.

All 'struct XXX *' have the same representation. All 'union XXX *' have
the same representation. That's from 6.2.5p27. So if your users are
going to be using arbitrary new "primitive types" and they are exactly C
structures or unions, perhaps this knowledge can benefit you, by
preventing your pointer representations from being theoretically
infinite in variety.
 
M

Morris Keesan

float f = 3.14;
int i = 0;
memcpy(&i, &f, sizeof (int));

This will "copy some bits from f to i", but it's not necessarily
a safe thing to do. If float happens to be bigger than int,
it will copy past the end of i, resulting in undefined behavior.

Um, no. Read the code again. If int happens to be bigger than float,
it will read past the end of f (also resulting in undefined behavior).
But memcpy(&dest, &src, sizeof dest) can't write past the end of dest,
and (sizeof f > sizeof i) won't cause any problems in the above.
 
K

Keith Thompson

Morris Keesan said:
Um, no. Read the code again. If int happens to be bigger than float,
it will read past the end of f (also resulting in undefined behavior).
But memcpy(&dest, &src, sizeof dest) can't write past the end of dest,
and (sizeof f > sizeof i) won't cause any problems in the above.

You're right, I flipped a mental bit.

Of course it still has the same problems with storing a meaningless
value (best case) or trap representation (worst case) in i.
 
J

James Kuyper

Marco Devillers said:
Hi all, a short question.
I wrote a compiler which compiles to C and has a garbage collector
written in C. The garbage collector assumes that nodes in memory are
arrays of integers or pointers (I use the default integer of pointer
size type for that).

It would help a lot if you showed some code to make the question
more specific. �Obvious first question: �is the format of a Node
(ignoring the cases with floats, etc) like this

� �struct Node_s {
� � � union {
� � � � �some_integer_type � integers[ ELEMENTS_PER_NODE ];
� � � � �struct Node_s � � �*pointers[ ELEMENTS_PER_NODE ];
� � � } element_arrays;
� �};

Excellent! No, a node is just a series of cells, integers or pointers,
so I didn't define an explicit node type. Referring to a node is just
intptr_t* node, though there are a number of invariants. For brevity,
lets assume that the first value is always an integer and tells you a)
the size and b) whether the following bits are integers (a terminal
node) or pointers (a non-terminal). (It's more complex, stuff may mix
since it is a conservative collector, but this will do.)

So, I sometimes store floats, the bits, into the memory of a terminal
node starting with the second cell. But I would like it if people are
able to add new basic types to the language such as pairs of floats
for an OpenGL binding. So, a priori, I have no knowledge of what data
is stored in the payload of a terminal node.

If you don't know the type of the payload, how are you deciding what
kind of object you want to copy it into?

If all you know about the payload is it's size, then the only thing you
can do with it is memcpy it into or out of a buffer. As long as you make
no attempt to read the value of the object you use as a buffer, and just
use it as a destination and source of memcpy() calls, it doesn't really
matter what type it has; all that matters is making sure that it's big
enough.

However, my preference would be to use an array of unsigned char; that
guarantees that you can actually safely examine what you've got in the
buffer. In particular, 6.2.6.1p4 guarantees that for an object with a
size of n bytes, "The value may be copied into an object of type
unsigned char [n] (e.g., by memcpy); the resulting set of bytes is
called the object representation of the value."
 
O

Oliver Jackson

Um, no.  Read the code again.  If int happens to be bigger than float,
it will read past the end of f (also resulting in undefined behavior).
But memcpy(&dest, &src, sizeof dest) can't write past the end of dest,
and (sizeof f > sizeof i) won't cause any problems in the above.

Last time someone said "um, no," to me, I smacked him so hard his
boner didn't stop shaking until next week. Word to the wise: watch
the 'tude, dude.


 
K

Keith Thompson

Oliver Jackson said:
Last time someone said "um, no," to me, I smacked him so hard his
boner didn't stop shaking until next week. Word to the wise: watch
the 'tude, dude.

Last time someone said "um, no" to me, it was Morris Keesan pointing out
a silly error I had made, and I was grateful for the correction. I
don't know why you feel the need to jump in, but I suggest you watch
your own "'tude"' (and your language; this is a public forum).
 
J

J. J. Farrell

Oliver said:
Last time someone said "um, no," to me, I smacked him so hard his
boner didn't stop shaking until next week. Word to the wise: watch
the 'tude, dude.

I suggest you get some help for your anger and irrational response problems.
 

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
474,091
Messages
2,570,605
Members
47,225
Latest member
DarrinWhit

Latest Threads

Top