Let's say I perform the following:
void g(int* x)
{
int y = 0;
auto diff = uintptr_t(&y) - uintptr_t(x);
}
void f()
{
int x = 0;
g(&x);
}
Does diff
merely have undefined value, or does the code invoke undefined behaviour? According to the specification, is the code guaranteed to run nicely and compute a value for diff
, possibly meaningless, or does it invoke UB? I believe there's something about unrelated variables, but could not pinpoint it.
I'm interested in answers regarding any standard since (including) C++ 11.
Discussion arose from comments in: Print stack in C++
In computer programming, undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres.
Undefined Behavior results in unpredicted behavior of the entire program. But in unspecified behavior, the program makes choice at a particular junction and continue as usual like originally function executes.
Undefined behavior (often abbreviated UB) is the result of executing code whose behavior is not well defined by the C++ language. In this case, the C++ language doesn't have any rules determining what happens if you use the value of a variable that has not been given a known value.
Undefined behavior exists mainly to give the compiler freedom to optimize. One thing it allows the compiler to do, for example, is to operate under the assumption that certain things can't happen (without having to first prove that they can't happen, which would often be very difficult or impossible).
To quote the C++11 standard draft. On the subject of converting a pointer to an integer
[expr.reinterpret.cast]
5 A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.
Since uintptr_t
must be defined for the your code to compile, then there exists an integer type on the target machine capable of being the target of the pointer-to-integer conversion. The mapping is implementation defined, but most importantly the result is not indeterminate. This means you obtain some valid integer for both conversions.
So the subtraction is not undefined behavior. But the result is implementation defined.
Converting pointer to integer of sufficient size is well defined, subtracting unsigned integer from another is well defined regardless of their value. There is no undefined behaviour here.
But also, standard doesn't guarantee any particular value for the converted integers, and therefore neither for the result of their subtraction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With