|
From: Patrick J. L. <lop...@gm...> - 2013-02-04 17:25:57
|
Very bad idea. Accessing pointers via the "wrong" type is undefined
behavior, and the compiler is free to assume you do not do that.
In simple cases, GCC with -Wall will warn you about this
("Dereferencing type-punned pointer will break strict-aliasing
rules"). Here is a simple test program illustrating the principle:
=====
#include <stdio.h>
struct A { int x; };
struct B { int x; };
int
foo(struct A *a, struct B *b)
{
a->x = 1;
b->x = 2;
return a->x;
}
int
main(int argc, char *argv[])
{
struct A a;
printf("%d\n", foo(&a, (struct B *)&a));
return 0;
}
=====
Compile this with optimization and it will probably print "1"; compile
without optimization, and it will probably print "2". (I say
"probably" because in the presence of undefined behavior the compiler
is free to emit any code whatsoever.)
Never access an object via the wrong pointer type. The only exception
is "char *", which can alias anything by definition. (You can also
use a union to access the same memory as different types. I believe
this takes you into the realm of implementation-defined behavior.
That is also bad, in my opinion, but it is not the disaster of
undefined behavior.)
Speaking of "char *", the memcmp() proposal is also a bad idea.
Compilers are free to insert padding into structures however they
like. Are you sure no compiler on any platform ever would choose to
pad this structure to 64 bits? In that case, memcmp() would be
comparing uninitialized bits.
If you want to go the struct route, just compare the structs
field-wise and convince the compiler writers to optimize it. Or maybe
use a union if you want to compare the structures as integers, with
assertions that everything has the size you expect.
Finally, as long as I am on my soap box... In my humble opinion, it
is generally a bad idea to use memcmp(), memcpy(), or memset() on
anything other than actual byte arrays. To zero-initialize a
structure, instead of using memset(), just use:
struct HReg foo = { };
This is shorter to write, easier to read, and it will properly
initialize floats/doubles/pointers, even on platforms that do not use
all-zero as the byte representation for 0.0 or NULL.
To reinitialize a structure to zero:
static const struct HReg empty = { };
struct HReg foo;
...
foo = empty;
Any compiler worth its salt will generate optimal code for these.
- Pat
On Sun, Feb 3, 2013 at 4:47 AM, Дмитрий Дьяченко <di...@gm...> wrote:
> Fedora 17/x64
> gcc-4.7.2 -O2 -S tst.c
>
> typedef struct {
> unsigned regno : 27;
> unsigned class : 4;
> unsigned virtual : 1;
> } HReg;
>
> static inline int cmp_Hreg(const HReg* lhs, const HReg* rhs)
> {
> const int a = *(int*)lhs;
> const int b = *(int*)rhs;
> return a == b;
> }
>
> int foo(const HReg* lhs, const HReg* rhs)
> {
> return cmp_Hreg(lhs, rhs);
> }
>
>
> .globl foo
> .type foo, @function
> foo:
> .LFB1:
> .cfi_startproc
> movl (%rsi), %eax
> cmpl %eax, (%rdi)
> sete %al
> movzbl %al, %eax
> ret
>
>
> Tnanks,
> Dmitry
>
> 2013/2/3 Eric Pouech <eri...@or...>:
>> Le 01/02/2013 21:26, Florian Krohm a écrit :
>>> On 01/31/2013 11:50 AM, Florian Krohm wrote:
>>>> Hmm, maybe we should bite the bullet and make HReg a struct after all.
>>>> Let me see how generated code looks like....
>>>>
>>> I looked at two implementation choices:
>>>
>>> 1) make HReg a proper struct
>>>
>>> typedef struct {
>>> UInt regno : 24;
>>> HRegClass class : 4;
>>> Bool virtual : 1;
>>> } HReg;
>> and what does sameHReg: toBool(*(UInt*)&r1 == *(UInt*)&r2)) provides ?
>> (assuming sizeof(HReg)==sizeof(UInt))
>> A+
>>
>>
>> ------------------------------------------------------------------------------
>> Everyone hates slow websites. So do we.
>> Make your web apps faster with AppDynamics
>> Download AppDynamics Lite for free today:
>> http://p.sf.net/sfu/appdyn_d2d_jan
>> _______________________________________________
>> Valgrind-developers mailing list
>> Val...@li...
>> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
>
> ------------------------------------------------------------------------------
> Everyone hates slow websites. So do we.
> Make your web apps faster with AppDynamics
> Download AppDynamics Lite for free today:
> http://p.sf.net/sfu/appdyn_d2d_jan
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
|