Your code makes two very ugly assumptions:
1) sizeof(long) == sizeof(unsigned)
I assume you're working in 32-bit mode (not x86_64) so this assumption
is not your problem.
2) hl uses the same storage as *((long*)&hl)
That is almost certainly your problem. It may seem an obvious
assumption, but it is incorrect.
There are several work arounds. The most portable (to compilers other
than GCC) is to use unions rather than casts when you want data of
different types to share storage.
If this problem occurs a moderate number of times in your code, the best
solution in GCC is "may_alias" which you can find in section 5.32 of the
documentation.
For example:
typedef long __attribute__((__may_alias__)) long_alias;
Then use *((long_alias*)(whatever)) instead of *((long*)(whatever))
anyplace that whatever is accessed as some other type within the view of
the optimizer.
If this problem is all over a big legacy code project, then you must
turn off strict-aliasing for the whole compile (see section 3.10 in the
documentation).
wcrotty wrote:
Hello,
I'm building an older codebase on RE5 and the casting of a long pointer is
somehow not working. It works when i compile on RE4.
RE5 compiler is gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
RE4 compiler is gcc (GCC) 3.4.3 20050227 (Red Hat 3.4.3-22.1)
Here is an example of the code.
char *hdr ;
char *p;
unsigned hl;
hdr = malloc(256 );
p=hdr;
hl = 32;
*((long *)(p)) = *((long *)(&hl));
hl = 0;
*((long *)(&hl)) = *((long *)(p));
printf("hl = %d p = %x\n",hl,p);
p+=4 ;
Now if i change the long * to int * the RE5 compiler works fine.
This isn't a compile error its a run time unexpected value error.