By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,225 Members | 2,187 Online
Bytes IT Community
+ Ask a Question
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
Share this Question
Share on Google+
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 <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"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 <b...@cs.stanford.eduwrote:
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 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.
The aliasing rules allow anything to be aliased as char,
I think. However, the behaviour would be undefined if
arrayA is not correctly aligned for a struct mystruct.

Aug 29 '07 #4

P: n/a
Old Wolf <ol*****@inspire.net.nzwrites:
On Aug 29, 8:33 am, Ben Pfaff <b...@cs.stanford.eduwrote:
>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 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.

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 <oldw...@inspire.net.nzwrote:
<snip>
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 <oldw...@inspire.net.nzwrote:
<snip>
>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];
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 <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"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 <oldw...@inspire.net.nzwrote:
<snip>
>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?
Yes. No, a union may also
have padding.
>
By the way - is a struct (or union) aligned according to its size, or
according 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 <sc******@doezl.netwrites:
[...]
A struct is aligned to insure that every member is also properly
aligned.
At least.
Since all the members of a union overlap, it is aligned according the
strictest alignment of its members.
At least.

A struct or union may be more strictly aligned than any of its
members. For example, an implementation might choose to give all
structs and union 4-byte alignment, even if they contain only
character members.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"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.