4 ms·
I like the behavior of the compiler here. There is no guarantee that a and b are next to each other in memory. That's why the comparison fails, the alternative
by bluecalm 8y ago
I like the behavior of the compiler here. There is no guarantee that a and b are next to each other in memory. That's why the comparison fails, the alternative makes is runtime/compiler/optimization level dependent which would be a total mess.
As usual with those C bashing articles you won't run into trouble if you don't try very hard to write contrived code.
I mean, the moment you see:
int *q = &b + 1;
on your screen alarm bells should go off. Doing pointer arithmetic on something that is not an array is asking for trouble. If the standard should be amended in any way it should be undefined behavior right away you do pointer arithmetic on non-array objects.
- jstimpfle 8y agoThat would require making a distinction between array-pointers and non-array pointers. There, another can of worms. Probably not worth the additional complexity.
- mpweiher 8y agoAgree on the alarm bells with the pointer arithmetic. Disagree that gcc is doing the right thing here. The clang behavior (different comment in this thread) is much more sane: if the pointers happen to be the same, they compare as equal. If the pointers happen to not be the same, they compare as not equal.
- shakna 8y agoExcept clang's behaviour changes depending on the optimisation level. If you use -O1, then you get a different result.
- mpweiher 8y agoYes, because the pointers are different at -O. As there are no guarantees as to the relative placement of auto/stack variables relative to each other, that is perfectly fine.
- deleted 8y ago[deleted]
- Koshkin 8y agoC is useful in part because it allows for the freedom unimaginable in other languages.
- pjmlp 8y agoThat freedom does exist in Ada, Modula-2 among others, the big difference being that one needs to be explicit about what is going on.
- tzs 8y ago> I like the behavior of the compiler here. There is no guarantee that a and b are next to each other in memory. That's why the comparison fails, the alternative makes is runtime/compiler/optimization level dependent which would be a total mess Yes, there is no guarantee that they are next to each other, but in this case they happen to be next to each other, and according to the spec as quoted in the article, two pointers are equal if: > [...] one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space Note that it says "happens to" immediately follow, not "is guaranteed to" immediately follow. This are pointers to ints, not arrays of ints, but that should not matter because as quoted in the article: > 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. I don't see any way to read these as not requiring the pointers to compare as equal if the compiler happens to put a and b adjacent in memory in the right order and with no padding between them, other than resorting to something ridiculous like claiming that "follow" or "immediately" follow are not defined in the spec and so one object occupying that very next available address after another does not necessarily "immediately follow". This seems to be what the gcc developers went with to declare this is not a bug. Also, note that if you move the "int a, b" to outside main, so a and b are on the heap instead of on the stack, then gcc does find that the pointers are equal.
- clarry 8y ago> > 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. > I don't see any way to read these as not requiring the pointers to compare as equal if the compiler happens to put a and b adjacent in memory in the right order and with no padding between them, other than resorting to something ridiculous like claiming that "follow" or "immediately" follow are not defined in the spec and so one object occupying that very next available address after another does not necessarily "immediately follow". This seems to be what the gcc developers went with to declare this is not a bug. "These operators" in the spec refer to the (additive) pointer arithmetic operators, not the equality operator. So incrementing a pointer to int behaves as if the pointee were in an array of length one, but that does not mean any subsequent equality operator should consider the objects as arrays. It's totally fine for the equality comparison to return false when the objects in question are actually not arrays.