F
ficedula
Guest
To ficedula:
Ding ding ding ding! Congratulations on being the first to note that some of these are undefined.There are two intentions here:
1: Bring about more awareness towards the types of things you should avoid while coding because the results may not be consistent across compilers.
2: Have a bit of fun by logically deducing what should happen if the ANSI C/C++ specification is not obscured by implementation. The ANSI C++ specification says explicitly that values modified twice between sequence points yield undefined results, however the actual result can be logically deduced.
Well, if by "logically deduced" you mean, "make a reasonable guess about what a particular version of a particular compiler might do", then yeah, you can do that. But undefined means just that: the compiler can legally do anything and remain spec-compliant. Can even change between compiler versions, which is why it's never any better than a guessing game.
2: For all intents and purposes, there is no need to explain that the int pointers aren’t valid addresses; that much is clear at first glance. But you are correct to deduce that the specifications don’t specifically define that the validity of constant pointers be verified at all during compilation (in fact doing so may lead to erroneous output across systems), so the result of constants 6 and 2 are just as valid as constants 0x100006 and 0x100002 (and both yield the same result).
Bzzzzt, wrong? I don't believe the C++ spec mandates that pointers have to be simple integers containing the raw memory address they're pointing to. The three issues here are:
1) On systems where memory operations have to be aligned, 0x6 (and 0x100006) could never, ever point to an int [of 32-bits or more], and therefore while I suspect the spec doesn't cover this, trying to calculate the difference in indices between two locations when neither location can hold the value in question is ... dodgy.
2) I also believe - although I'm not sure - that the spec says that pointer comparisons between arbitrary values are undefined! ie. you can compare pointers into a block returned from a single call to malloc/new, or you can compare pointers into an array, but comparing any two pointers is not guaranteed to do anything meaningful.
This would also mean the comparison could return literally anything.
3) On some systems, pointers actually contain more information than a memory address: for example, the low order bits contain information such as the type, size and format of data being pointed to, while the high order bits contain the actual addressing information. The comparison rule above is a direct consequence of C++ wanting to allow arbitrary schemes like this (since this is how pointers work in hardware on some CPUs!).
Again, that means you have no idea what meaning 0x2 or 0x6 have as a pointer. It's possible 0x6 is actually setting the hardware pointer flags PTR_READ_FROM_RANDOM_MEMORY_LOCATION and PTR_INVALID. Therefore you can't be sure what the comparison will return.
1) On systems where memory operations have to be aligned, 0x6 (and 0x100006) could never, ever point to an int [of 32-bits or more], and therefore while I suspect the spec doesn't cover this, trying to calculate the difference in indices between two locations when neither location can hold the value in question is ... dodgy.
2) I also believe - although I'm not sure - that the spec says that pointer comparisons between arbitrary values are undefined! ie. you can compare pointers into a block returned from a single call to malloc/new, or you can compare pointers into an array, but comparing any two pointers is not guaranteed to do anything meaningful.
This would also mean the comparison could return literally anything.
3) On some systems, pointers actually contain more information than a memory address: for example, the low order bits contain information such as the type, size and format of data being pointed to, while the high order bits contain the actual addressing information. The comparison rule above is a direct consequence of C++ wanting to allow arbitrary schemes like this (since this is how pointers work in hardware on some CPUs!).
Again, that means you have no idea what meaning 0x2 or 0x6 have as a pointer. It's possible 0x6 is actually setting the hardware pointer flags PTR_READ_FROM_RANDOM_MEMORY_LOCATION and PTR_INVALID. Therefore you can't be sure what the comparison will return.