struct usb_line6 *line6 = &podhd->line6;
The assumption is that this is OK so long as you don't try to access the contents of line6 without doing some upstream null checking first. This assumption is false. The very act of dereferencing is undefined, regardless of whether you access the resulting address or not.The assumption fails whether null is implemented as 0, 200, 0x8000000000000000, 0xffffffffffffffff.
That becomes a problem with modern optimizing compilers, because they make assumptions about your code based on what's allowed according to the spec.
struct usb_line6 *line6 = &podhd->line6;
Offset is calculated "below the hood". Pointer arithmetic is defined with arithmetic operands: +,--> and . are not arithmetic operands.
If you look at the definition of the -> and [], you might learn something!
[] operator doesn't have any place in this debate.
What @jwatte tried to say is that `->` works like this:
// foo is struct thingity*
&foo->bar == foo + offsetof(struct thingity, bar);
The `[]` does a similar thing: // s is char*
*(s+i) == s[i]It does however specify that [] operator is equivalent to pointer arithmetic. But we are talking ->,. operators and not [].
C standard 3.2.2.3: "An integral constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant."
C standard 4.1.5: "The macros are... NULL, which expands to an implementation-defined null pointer constant."
See [1] for more info.
[1]: http://stackoverflow.com/questions/2599207/can-a-conforming-...
See also http://stackoverflow.com/questions/2597142/when-was-the-null...
There is no requirement for an integer-to-pointer conversion to retain the bit pattern of the integer value, any more than an integer-to-floating-point conversion is required to do so.
In most modern implementations, conversions among integer and pointer types of the same size are trivial, simply reinterpreting the bits as a value of a different type.
A conforming C or C++ compiler can use, for example, the bit pattern 0xFFFFFFFF to represent a null pointer. Converting a constant 0 to a pointer type would yield a pointer with the representation 0xFFFFFFFF. Converting a non-constant 0 to a pointer type does not necessarily yield a null pointer; the result is implementation-defined, and may be indeterminate garbage.