Hi GCClers,

I searched hard, but couldn't determine conclusively if the C standard allows to alias a void* pointer with a char* pointer.

If that's not undefined behavior, then the following may be a glitch in GCC 4.1.0 when compiled with -O2.

Here's the ugly minimal piece of code:

/* ASSUME pointer POINTS TO AN INTEGER THAT SPECIFIES THE INCREMENT
   ================================================================ */
int increment(int *pointer)
{ return(*pointer); }

/* INCREMENT A POINTER BY THE NUMBER OF BYTES POINTED TO
   ===================================================== */
void *incremented(void *pointer)
{ int inc=increment(pointer);
  *((char**)&pointer)+=inc;
  return(pointer); }

What goes wrong is that the function incremented() increments the pointer, but returns the original, non-incremented value.

Here's the assembly code:

Dump of assembler code for function incremented:
0x08051f80 <incremented+0>:     push   %ebp
0x08051f81 <incremented+1>:     mov    %esp,%ebp
0x08051f83 <incremented+3>:     push   %ebx
0x08051f84 <incremented+4>:     sub    $0x4,%esp
0x08051f87 <incremented+7>:     mov    0x8(%ebp),%ebx
0x08051f8a <incremented+10>:    mov    %ebx,(%esp)
0x08051f8d <incremented+13>:    call   0x8051f70 <increment>
0x08051f92 <incremented+18>:    add    %eax,0x8(%ebp)
0x08051f95 <incremented+21>:    mov    %ebx,%eax
******************************************************************
-->> Here's the problem, line above should read mov 0x8(%ebp),%eax
******************************************************************
0x08051f97 <incremented+23>:    add    $0x4,%esp
0x08051f9a <incremented+26>:    pop    %ebx
0x08051f9b <incremented+27>:    pop    %ebp
0x08051f9c <incremented+28>:    ret
0x08051f9d <incremented+29>:    lea    0x0(%esi),%esi


Thanks for your time, and BTW: is there a 'better' construct for incrementing a void* pointer other than *((char**)&pointer)+=inc ? ;-)

Greetings,
Elmar

Reply via email to