问题
this is my struct :
struct Node {
struct Node* data;
struct Node* links[4];
}
assuming there is no padding, does Node->links[-1] guaranteed to be pointing on Node::data ?
回答1:
No guarantee; this is undefined behaviour:
- Compiler-dependent structure padding
- Standard only defines array indexing between 0 and length (inclusive)
Possible strict-aliasing violation
In practice, it's quite possible that you will end up pointing at data, but any attempts to access it will result in UB.
回答2:
Array subscripting is defined in terms of pointer arithmetic, and the C99 standard has this to say about pointer arithmetic:
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.
So accessing Node->links[-1] (even just getting the address of Node->links[-1]) is undefined behavior, strictly speaking. So you have no guarantee that Node->links[-1] will get you Node::data.
But as many commentators mention, it will work pretty much always. I'd still consider it poor programming practice that should be avoided. If not for the technicality, then because it requires that modifications to struct Node can easily cause bugs that the compiler will not help you with. When someone adds something between data and links, things will mysteriously break.
回答3:
A union might help you here. Something like this:
struct Node {
union {
Node *data;
struct {
Node *lnk[5];
} links;
}
}
回答4:
I'd say yes, but why then don't declare it as
struct Node {
struct Node* links[5];
}
回答5:
Almost Yes
Yes, it almost certainly will point at data, but it may not be precisely a guaranty.
You actually do get a guaranty that x[-1] is the same thing as *(x - 1), so, depending on what you put at the address of x - 1, then you do have a sort of guaranty. (And don't forget that when subtracting from pointers, the decrement is by the size of the item.)
Although others have objected on the basis of strict aliasing, in this case the types are the same so the elaborate optimizations should not remove your expected behavior.
回答6:
I think it is. But it's not guaranteed by the standard that there is no padding.
Edit: but the standard also says that behavior is undefined if "An array subscript is out of range, even if an object is apparently accessible with the given subscript".
回答7:
This is implementation defined, depending on how the implementation pads structures and arrays. However, as long as it pads structs and arrays the same way, it should work.
来源:https://stackoverflow.com/questions/4006736/c-negative-array-index