5 ms·
Subtraction of arbitrary pointers is not legal.
by sigjuice 9y ago
Subtraction of arbitrary pointers is not legal.
- marcoperaza 9y agoYou're technically right, because you can have C compilers for architectures with all sorts of weird memory semantics. But in reality, this will work as expected on all of the major platforms and give you the relative positions of the variables on the stack. The C standard is not the final say on things, your compiler and platform are. The standard is merely the minimum specifications that are ideally to be supported on all platforms, however you will still be unpleasantly surprised if you rely on it as such.
- ajross 9y agoIt's not defined by the language standard. Real machine addresses have values and can be compared.
- lomnakkus 9y agoWhat does "can be compared" mean? To me it means that "<=>" [1] is well-defined. It doesn't say anything about numerical values. [1] Spaceship operator. Think "return value of memcmp" but generalized to any operand types.
- YSFEJ4SWJUVU6 9y agoAny valid pointer values can be compared for equality. Only pointers that point within a single object (like an array, or a struct) can be compared for ordering. Nesting doesn't matter as long as down the line there's a common "parent" of sorts. (That is, if you want to have well-defined behaviour.) (Edit: and for any pointers that you can compare for ordering, you may also calculate their offset from one another. However, like GP said, in practice you can do that for any pointers on common platforms.)
- ajross 9y agoNo, real pointer values have numerical values. They are numbers, period. You guys are getting balled up thinking about the language standard as the "ultimate reference of truth" in the argument. When the whole point of the linked article is about pointing out that, no, the behavior of the actual machine being used is a more important "truth" in some contexts.
- adrianN 9y agoWell, if it's not in the standard, the compiler might disagree with you and produce output different from what you expect. You're not programming the actual machine, you're communicating intended program behavior to the compiler, who programs the actual machine. If you want to avoid misunderstandings between you and the compiler, you'd better adhere to the language definition.
- Avernar 9y agoIf you are writing normal code then yes. But there are always exceptions. One is trying to learn how your current target architecture actually works. This is not production code. It's a "where in memory did the compiler decide to put that" question. You may get the results you expect or you may get someting totally bizzare. But since the purpose is discovering how the compiler works there is no wrong result. Another is if you are writing your own memory manager. Here there are a lot of pointer comparisons to not the same allocated objects. But a memory manager is very OS and architecture specific so you will probably have to rewrite it when porting the code. Having said all that, I wouldn't subtract the two void pointers like the example did. I would have converted them both to integers first and then subtract. Again, since this is for debugging and/or learning purposes then it's OK to bend the language rules a bit.
- pjmlp 9y agoThat value of truth is what allows C compilers to wipe out your beloved code on -O3, because you just feel entitled to write UB code.
- YSFEJ4SWJUVU6 9y agoWell, you can compare pointers (to distinct objects) too, but only for equality. (The only in any case not-undefined way of calculating some sort of difference value between such is with the use of the optional uintptr_t, but I'd guess this isn't a sort of undefined behaviour which triggers unwanted compiler tricks, anyway.)
- vardump 9y agoSay, you run on 8051. What should the comparison result be for idata pointer with value 4, and xdata pointer 4? What about kernels (Linux, Windows — doesn't matter)... how do you compare physical address pointer with virtual address pointer? Sure, they have values. But that might not mean much. Pointers can point to entirely different address spaces.
- ajross 9y agoExactly. The behavior of the actual machine matters! The C language standard defines (pretty imperfectly in the case of processors with multiple address spaces like the 8051 scratchpad RAM) something like a least common denominator you can rely on to "write portable C". But that's not truth, nor is "portable C" the goal to all engineering efforts. Pointers are numbers. Scratchpad registers can't have pointers taken to them. Those are truths, even if inconvenient.