From: Seebs on
On 2010-02-28, Moi <root(a)invalid.address.org> wrote:
> Please elaborate. IMHO, there is no reason to see a struct hack as a flaw.

Of course there is.

There exist compilers which will smack you down good if you access more than
one object in an array declared as containing one object.

That said, if you feel like you can trust that your compilers will have the
feature, you can use the C99 "flexible array member" (just omit the size of
an array declared at the end of a struct).

If the array is of characters, you can also cheat by declaring a pointer at
the end of the struct, allocating extra space, and setting the pointer to
point just past the struct (and thus into the extra space).

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Nicolas George on
Seebs wrote in message <slrnholl9c.s6g.usenet-nospam(a)guild.seebs.net>:
> There exist compilers which will smack you down good if you access more than
> one object in an array declared as containing one object.

But the "array", here, is the one allocated by malloc. You can put anything
you want anywhere in a memory area allocated by malloc. The structure member
is just a convenient way to compute a pointer inside that memory area.
From: Rainer Weikusat on
Nicolas George <nicolas$george(a)salle-s.org> writes:
> Seebs wrote in message <slrnholl9c.s6g.usenet-nospam(a)guild.seebs.net>:
>> There exist compilers which will smack you down good if you access more than
>> one object in an array declared as containing one object.
>
> But the "array", here, is the one allocated by malloc. You can put anything
> you want anywhere in a memory area allocated by malloc.

This is not true. A storage area allocated by malloc is required to be
'suitably aligned for any purpose' (for glibc, this means the pointer
value will be an integral multiple of eight). But this of course
doesn't 'magically' extend to the bytes which make up this area. Eg,
assuming that p points to the start of the area, p + 1 is not
'suitably aligned for any purpose' and this means that code like the
example one below

unsigned char *p;

p = malloc(5);
*(unsigned *)(p + 1) = 0xabcdef;

might either cause an alignment trap or some other non-desirable
effect (eg, on ARM9 with alignment traps disabled, the stored value
will be garbled). Even on x86, misaligned accesses incur a performance
penalty (which is an euphemism for 'alignment traps handled by hardware
on die due to general hopelessnes of this quest').
From: Moi on
On Sun, 28 Feb 2010 23:41:41 +0100, Rainer Weikusat wrote:

> Nicolas George <nicolas$george(a)salle-s.org> writes:
>> Seebs wrote in message <slrnholl9c.s6g.usenet-nospam(a)guild.seebs.net>:
>>> There exist compilers which will smack you down good if you access
>>> more than one object in an array declared as containing one object.
>>
>> But the "array", here, is the one allocated by malloc. You can put
>> anything you want anywhere in a memory area allocated by malloc.
>
> This is not true. A storage area allocated by malloc is required to be
> 'suitably aligned for any purpose' (for glibc, this means the pointer
> value will be an integral multiple of eight). But this of course doesn't
> 'magically' extend to the bytes which make up this area. Eg, assuming
> that p points to the start of the area, p + 1 is not 'suitably aligned
> for any purpose' and this means that code like the example one below
>
> unsigned char *p;
>
> p = malloc(5);
> *(unsigned *)(p + 1) = 0xabcdef;
>
> might either cause an alignment trap or some other non-desirable effect
> (eg, on ARM9 with alignment traps disabled, the stored value will be
> garbled). Even on x86, misaligned accesses incur a performance penalty
> (which is an euphemism for 'alignment traps handled by hardware on die
> due to general hopelessnes of this quest').

You are trying to make this into an alignment issue.
That was not the case. Please read the source.

AvK
From: Nicolas George on
Rainer Weikusat wrote in message <87r5o52day.fsf(a)fever.mssgmbh.com>:
> This is not true. A storage area allocated by malloc is required to be
> 'suitably aligned for any purpose' (for glibc, this means the pointer
> value will be an integral multiple of eight). But this of course
> doesn't 'magically' extend to the bytes which make up this area.

No, but:

- if pointer bar is aligned for any purpose, then it is in particular
aligned for struct foo;

- if pointer bar is aligned for struct foo, then taking the address of a
member gives a pointer suitably for the type of that member;

- if a pointer is suitably aligned for its type, then all arithmetic on that
pointer, barring a cast to another type, stays thusly aligned.

This implies that:

struct foo *p = malloc(sizeof(struct foo) + 42 * sizeof(qux_t));
qux_t q = &p->qux; /* assuming member qux has type qux_t */
q[42] = SOME_QUX_VALUE;

is always correct. With the caveat that, if qux is not the last element of
the structure, the last access may have wrecked havoc in the following
members, which must not be later accessed.
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: Forging IPv6 addresses?
Next: using select as a sleep call