Re: Aliasing: reliable code or not?
On Tue, Nov 28, 2006 at 11:36:19PM -0800, Ian Lance Taylor wrote: Or you can use constructor expressions to make this slightly more elegant, though I retain the assumptions about type sizes: char *foo1(char* buf){ memcpy(buf, (char[]) { 42 }, 1); buf += 1; memcpy(buf, (short[]) { 0xfeed }, 2); buf += 2; memcpy(buf, (int[]) { 0x12345678 }, 4); buf += 4; memcpy(buf, (int[]) { 0x12345678 }, 4); buf += 4; return buf; } Or even use mempcpy to make it even more compact: char * foo1 (char *buf) { buf = mempcpy (buf, (char[]) { 42 }, 1); buf = mempcpy (buf, (short[]) { 0xfeed }, 2); buf = mempcpy (buf, (int[]) { 0x12345678 }, 4); buf = mempcpy (buf, (int[]) { 0x12345678 }, 4); return buf; } Jakub
Aliasing: reliable code or not?
I have code that goes something like this: char *foo(char *buf){ *buf++ = 42; *((short*)buf) = 0xfeed; buf += 2; *((int*)buf) = 0x12345678; buf += 4; *((int*)buf) = 0x12345678; buf += 4; return buf; } The buffer is really of type char. The above comes from a pile of macros and inline functions (C99 code), or alternately from a pile of evil C++ templates. Real C99-compliance would be cute, but then again the buffer will end up getting executed as x86 code. Intentionally executing data is surely a standards violation of the highest order. I can't afford to just use char to do the writes. Currently gcc won't merge those into larger writes. Performance matters. So, how likely is gcc to do what I obviously want? It seems to be working right now... It would be nice to have this documented to work, just as was done with unions for type punning. The next best would be a big giant warning and a work-around that doesn't kill performance.
Re: Aliasing: reliable code or not?
I have code that goes something like this: char *foo(char *buf){ *buf++ = 42; *((short*)buf) = 0xfeed; buf += 2; *((int*)buf) = 0x12345678; buf += 4; *((int*)buf) = 0x12345678; buf += 4; return buf; } This does violate C aliasing rules. Here is how I would write it so you can get the best results: char *foo(char *buf) { short temp; int temp1; *buf++=42; temp = 0xfeed; memcpy(buf, temp, sizeof(temp)); buf+=sizeof(temp); temp1 = 0x12345678; memcpy(buf, temp1, sizeof(temp1)); buf+=sizeof(temp1); temp1 = 0x12345678; memcpy(buf, temp1, sizeof(temp1)); buf+=sizeof(temp1); return buf; } As using memcpy does not cause a violation of the aliasing rules. And does the correct thing: lis 11,0x1234 li 0,42 li 9,-275 ori 11,11,22136 stb 0,0(3) sth 9,1(3) stw 11,7(3) stw 11,3(3) addi 3,3,11 -- Pinski
Re: Aliasing: reliable code or not?
Andrew Pinski [EMAIL PROTECTED] writes: Here is how I would write it so you can get the best results: char *foo(char *buf) { short temp; int temp1; *buf++=42; temp = 0xfeed; memcpy(buf, temp, sizeof(temp)); buf+=sizeof(temp); temp1 = 0x12345678; memcpy(buf, temp1, sizeof(temp1)); buf+=sizeof(temp1); temp1 = 0x12345678; memcpy(buf, temp1, sizeof(temp1)); buf+=sizeof(temp1); return buf; } Or you can use constructor expressions to make this slightly more elegant, though I retain the assumptions about type sizes: char *foo1(char* buf){ memcpy(buf, (char[]) { 42 }, 1); buf += 1; memcpy(buf, (short[]) { 0xfeed }, 2); buf += 2; memcpy(buf, (int[]) { 0x12345678 }, 4); buf += 4; memcpy(buf, (int[]) { 0x12345678 }, 4); buf += 4; return buf; } Ian