N
Netocrat
Netocrat said:Jack Klein wrote:
<snip>
/* Assign array via struct */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LEN 20
typedef struct {
char a[LEN];
} S;
int main(void) {
S sa;
char A[LEN];
S *ps = malloc(LEN);
It's possible, but unlikely, that sizeof(S) > LEN due to padding. Better
to use sizeof(S) than LEN.
char *pa = malloc(LEN);
strcpy(sa.a, "Joe Wright Rocks");
puts(sa.a);
*(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.Given that element a must be located at the start of struct S, and that it
is a char array of size LEN, it's hard to see how it could be aligned
differently to the char array A of size LEN. Are you referring to this
specific case or in general? If this case, could you explain how the
standard allows the alignments to be different?
Type `char' has no alignment (ie. alignment(char) == 1), of course,
but at issue is not `char', but rather `char[10]'. Long time ago
Actually Joe's code #define's LEN to 20, you're thinking of the OP.
(don't ask me for details now) I read that on DEC stations character
arrays in structs could have different alignments depending on their
size, so for example `char[15]' could have different alignment than
`char[31]'. All this was for purpose of memory access speed; ordinarily
`char[ANY]' doesn't have alignment (at least when ANY is a prime number,
for others I don't know), but when in a struct, a compiler
could assume that the array is positioned at a "fast" location and
generate more optimal code. (BTW, the discussion in which I read it
was about why struct-hack didn't work.)
Well you've confirmed that it's not merely hypothetical - padding
actually is added in some real-world implementations. 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.
He meant "Chapter & Verse". :-D
The & did seem a little out of place...