Re: Array assignment via struct



On Sat, 06 Aug 2005 18:22:50 -0400, Joe Wright wrote:
> Netocrat wrote:
>>>>>Jack Klein wrote:
>>>>>>Joe Wright wrote:
<snip>
>>>>>>>#define LEN 20
>>>>>>>
>>>>>>>typedef struct {
>>>>>>> char a[LEN];
>>>>>>>} S;
>>>>>>>
>>>>>>>int main(void) {
>>>>>>> S sa;
>>>>>>> char A[LEN];
>>>>>>>
>>>>>>> S *ps = malloc(LEN);
<snip>
>>>>>>> *(S*)A = sa;
>>>
>>>[snip]
>>>
>>>>>>Here is where you invoke undefined behavior, since A isn't dynamically
>>>>>>allocated. There is no guarantee that A meets the alignment
>>>>>>requirements for an S. The compiler might generate code that assumes
>>>>>>that A is, causing some sort of trap on some platforms, or possible
>>>>>>misaligned data or overwriting the destination array.
<snip>
>> So to expand on
>> Jack's explanation of specific code being generated, perhaps something
>> like this:
>>
>> 4 padding bytes are added after the array of 20 char in the struct so
>> that it can be placed on an 8-byte boundary. The compiler generates
>> code to retrieve the elements of the array 8-bytes at a time and unaligned
>> access to 8-byte-wide data on this particular implementation is not
>> allowed.
>>
>> The automatic char[20] variable A is not aligned on an 8-byte boundary, so
>> when it's accessed through the struct, unaligned access occurs and our
>> implementation spits the dummy.
>>
>> So Joe - no go. Thou code be fraught.

Correction: thy code be fraught. Thou codest flawed source.

> I think not. Consider..
>
> struct {
> char a[17];
> } sa;
>
> ..and explain any case for sizeof sa not being 17. Annecdotes of long
> forgotten DEC Stations don't count.

Why not? Were they not valid C implementation hosts?

That's a contrived choice because being (2 pow 4) + 1 it's impossible to
minimise accesses. Using my example above, consider a 20-byte array
accessed in 8-byte chunks. When aligned on an 8-byte (or 4-byte)
boundary, it will take 3 accesses to read/write the entire array in
8-byte chunks. It will take 4 accesses to do the same when its alignment
is 1, 2 or 3 bytes off an 8-byte alignment. That's a supportable reason
for properly aligning the struct on an 8-byte boundary and hence requiring
4 padding bytes.

As for your 17 byte example, well, this implementation may pad out 7
bytes but more likely it would pad 3 and it would access 4 bytes at a time
on a 4-byte boundary.

Totally hypothetical but for all I know (I don't have a lot of varied
hardware experience) a machine like this does exist. Not the machine that
I work from though (Intel P4) because unaligned access whilst slower is
not an error.

.



Relevant Pages

  • Re: Array assignment via struct
    ... >> It's possible, but unlikely, that sizeof> LEN due to padding. ... >> Given that element a must be located at the start of struct S, ... >> differently to the char array A of size LEN. ... > arrays in structs could have different alignments depending on their ...
    (comp.lang.c)
  • Re: [JW] alignment problem for structures
    ... Is that enough to make the alignment requirements apply to ... Array elements include interelement ... >> alignment padding. ... to the start of the struct, then the assignment to *q1 will not "work". ...
    (comp.std.c)
  • Re: Does an array of char have alignment issues?
    ... The struct will have padding bytes so that its fields are aligned. ... Yes, the usual practice is to memcpyeach member of the structure, ... sizeofincludes padding needed to tile an array ...
    (comp.sys.arm)
  • Re: Struct assignment
    ... to copy padding bytes and padding bits. ... the value of a struct, and might not be copied -- as they ... Initializing an automatic array from a string ... literal is only guaranteed to initialize the ...
    (comp.lang.c)
  • Re: How to list the statement of all var ?
    ... > of an object when the question was about `var' statements? ... And as soon as i will test it for this particular host ... to use an Object object instead of an Array object. ...
    (comp.lang.javascript)