Hacker News new | past | comments | ask | show | jobs | submit login

Don't use `&h[1]` to refer to the space after a structure. I'm pretty sure that's undefined behavior

This is legal. '&h[1]' is a synonym for 'h + 1', thanks to C99 section 6.5.3.2 paragraph 3:

    ... if the operand is the result of a [] operator, neither the & operator
    nor the unary * that is implied by the [] is evaluated and the result is
    as if the & operator were removed and the [] operator were changed to a
    + operator.)
and that is valid thanks to C99 section 6.5.6, paragraphs 7 and 8:

    7. For the purposes of these operators, a pointer to an object that is
    not an element of an array behaves the same as a pointer to the first
    element of an array of length one with the type of the object as its
    element type.
    8. When an expression that has integer type is added to or subtracted
    from a pointer, the result has the type of the pointer operand. [...]
    Moreover, if the expression P points to the last element of an array
    object, the expression (P)+1 points one past the last element of the
    array object [...] If both the pointer operand and the result point
    to elements of the same array object, or one past the last element of
    the array object, the evaluation shall not produce an overflow; otherwise,
    the behavior is undefined. If the result points one past the last element
    of the array object, it shall not be used as the operand of a unary *
    operator that is evaluated.
So is 'h' points to an object it is entirely legal to compute '&h[1]'; whether you can dereference it is a separate question (and will depend on memory layout et cetera).



Ah, I forgot that "one past the last element" is excepted. I stand corrected. (Similar tricks, such as &h[-1], are indeed undefined behavior.)

Regardless, my point stands that it can give you the wrong alignment, if the elements you're putting after the header have greater alignment requirements than the header itself. E.g.:

    #include <stdint.h>
    struct foo { uint16_t a,b,c; }
    uint64_t *bar(struct foo *x) { return (uint64_t *) &x[1]; }
Gives you a misaligned pointer to an 8-byte object.

    #include <stdint.h>
    #include <stdint.h>
    struct foo { uint16_t a,b,c; uint64_t d[]; }
    uint64_t *bar(struct foo *x) { return x->d; }
That gives you a properly aligned pointer.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: