444,225 Members | 2,187 Online
Need help? Post your question and get tips & solutions from a community of 444,225 IT Pros & Developers. It's quick & easy.

# array copy via "struct-trickery"

 P: n/a Hi! OK, lets try "array-copy": { char arrayA[3]; arrayA = (char[]){1, 2, 3}; } it does *not* work since we're trying to make a fixed array-pointer arrayA, point to another location/address (where there is an "anonymous" array holding 1, 2 and 3) hmmm.... but have a look at this: /*** trickery-candy ****/ #define LEN 3 struct mystruct { char arr[LEN]; }; { char arrayA[LEN]; char arrayB[LEN] = {1, 2, 3}; *((struct mystruct *)arrayA) = (struct mystruct){{1, 2, 3}}; *((struct mystruct *)arrayA) = *((struct mystruct *)arrayB); } /***************/ ->it works! Using no memcpy (from string.h) or any other "normal method"!! Would the code for this be very similar to memcpy(arrayA, arrayB, sizeof(arrayA)); ??? (How does it compare?) (Any other ways of doing this?) Regards -Albert Aug 28 '07 #1
8 Replies

 P: n/a an*******@gmail.com writes: #define LEN 3 struct mystruct { char arr[LEN]; }; { char arrayA[LEN]; char arrayB[LEN] = {1, 2, 3}; *((struct mystruct *)arrayA) = (struct mystruct){{1, 2, 3}}; *((struct mystruct *)arrayA) = *((struct mystruct *)arrayB); } I'd recommend not doing that. For one thing, the compiler is allowed to insert padding at the end of 'struct mystruct', so that the structure assignment will actually write beyond the end of the array. For another, even in the absence of trailing padding, I suspect that the behavior is undefined given C's aliasing rules. -- "Your correction is 100% correct and 0% helpful. Well done!" --Richard Heathfield Aug 28 '07 #2

 P: n/a an*******@gmail.com writes: OK, lets try "array-copy": [snip] > hmmm.... but have a look at this: /*** trickery-candy ****/ #define LEN 3 struct mystruct { char arr[LEN]; }; { char arrayA[LEN]; char arrayB[LEN] = {1, 2, 3}; *((struct mystruct *)arrayA) = (struct mystruct){{1, 2, 3}}; *((struct mystruct *)arrayA) = *((struct mystruct *)arrayB); } /***************/ ->it works! Using no memcpy (from string.h) or any other "normal method"!! Sure. You can't assign arrays, but you can assign structures, even if the structures have members that are arrays. Would the code for this be very similar to memcpy(arrayA, arrayB, sizeof(arrayA)); ??? (How does it compare?) There's no reason to assume that the generated code would be different, since it's doing exactly the same thing. The struct assignment could well be implemented as a call to memcpy() -- or the memcpy() call could be implemented as a sequence of MOVE instructions (or whatever your CPU provides). I'd just use memcpy() because it's clearer. (Any other ways of doing this?) Undoubtedly, but how many ways do you need? -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 28 '07 #3

 P: n/a On Aug 29, 8:33 am, Ben Pfaff

 P: n/a Old Wolf anon.a...@gmail.com writes: { char arrayA[LEN]; char arrayB[LEN] = {1, 2, 3}; *((struct mystruct *)arrayA) = (struct mystruct){{1, 2, 3}}; *((struct mystruct *)arrayA) = *((struct mystruct *)arrayB); } I'd recommend not doing that. For one thing, the compiler isallowed to insert padding at the end of 'struct mystruct', sothat the structure assignment will actually write beyond the endof the array. For another, even in the absence of trailingpadding, I suspect that the behavior is undefined given C'saliasing rules. The aliasing rules allow anything to be aliased as char, I think. Sure. I am not enough of an expert on C's aliasing rules to know whether a struct encapsulating an array of char would follow the same aliasing rules as an array of char. I suspect that it would not. However, the behaviour would be undefined if arrayA is not correctly aligned for a struct mystruct. That's a third reason not to do this. Thank you. -- char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[] ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+ 2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}} Aug 29 '07 #5

 P: n/a On Aug 29, 2:18 am, Old Wolf However, the behaviour would be undefined if arrayA is not correctly aligned for a struct mystruct. Could it ever happen that arrayA is not correctly aligned with struct mystruct, given the following: #define LEN 3 struct mystruct { char arr[LEN]; }; char arrayA[LEN]; Might the struct have padding? Would a union change the situation? By the way - is a struct (or union) aligned according to its size, or according to the largest component it contains? Thanks -Albert Aug 29 '07 #6

 P: n/a an*******@gmail.com writes: On Aug 29, 2:18 am, Old Wolf >However, the behaviour would be undefined ifarrayA is not correctly aligned for a struct mystruct. Could it ever happen that arrayA is not correctly aligned with struct mystruct, given the following: #define LEN 3 struct mystruct { char arr[LEN]; }; char arrayA[LEN]; Yes. Note that compilers are likely to allocate objects on stricter alignment boundaries than they really need to, so code that assumes arrayA is strictly aligned may happen to work (until it breaks at the most inconvenient possible moment). Might the struct have padding? Yes. Would a union change the situation? No. By the way - is a struct (or union) aligned according to its size, or according to the largest component it contains? The alignment for a struct or union is at least the alignment for its most strictly aligned member. It may be more strict. For any type, the size must be a whole multiple of the alignment. For example char always has one-byte alignment. An implementation might require, say, 4-byte alignment for all structures. In that case, this structure: struct foo { char c; }; would have 4-byte alignment; it would therefore have to have at least 3 bytes of padding after 'c'. This is just one possibility; a compiler is also free to set the size and alignment of 'struct foo' to 1 byte. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 29 '07 #7

 P: n/a On Wed, 29 Aug 2007 02:19:02 -0700, an*******@gmail.com wrote: >On Aug 29, 2:18 am, Old Wolf >However, the behaviour would be undefined ifarrayA is not correctly aligned for a struct mystruct. Could it ever happen that arrayA is not correctly aligned with structmystruct, given the following:#define LEN 3struct mystruct { char arr[LEN];};char arrayA[LEN];Might the struct have padding? Would a union change the situation? Yes. No, a union may also have padding. >By the way - is a struct (or union) aligned according to its size, oraccording to the largest component it contains? A struct is aligned to insure that every member is also properly aligned. Since all the members of a union overlap, it is aligned according the strictest alignment of its members. Remove del for email Aug 31 '07 #8

 P: n/a Barry Schwarz San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 31 '07 #9

### This discussion thread is closed

Replies have been disabled for this discussion.