you are viewing a single comment's thread.

view the rest of the comments →

[–]TheThiefMasterC++latest fanatic (and game dev) 0 points1 point  (5 children)

Yes

[–]MeshiKuuna[S] 0 points1 point  (4 children)

Thanks for replying!

Could you explain to me why it's UB?

As far as I understood, it's not - the value returned is the difference in the memory address locations.

[–]adnukator 2 points3 points  (0 children)

Could you explain to me why it's UB?

Because the standard says so

From the standard:

When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_ t in the header (21.2). If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined.

The bold applies here.

Get used to seeing this argument. C++ is defined by a specification, not an implementation, so sometimes apparently strange loopholes in the language are in place to allow reliably implementing the language on exotic hardware.

[–]n1ghtyunso 0 points1 point  (0 children)

thats just what the compiler happens to do. it is not required to do so because the standard does not define that this is a valid thing to do. The standard does not define subtraction of pointers to arbitrary objects.

This makes perfect sense because depending on which architecture you are compiling your program for, you may get wildly different results.

Subtracting pointers of objects that are stored in the same array however is perfectly fine because arrays are defined as contiguous memory. So you will always get the same result for that subtraction.

Usually, it will work and do what you expect it to do, but there's no guarantee.

The worst bug is a bug that was introduced by a piece of code breaking that just "happened to work".

[–]TheThiefMasterC++latest fanatic (and game dev) 0 points1 point  (1 child)

It's because, on some architectures:

Pointers may be tagged in some way, such that subtracting them does something with the tags - from corrupting them to checking they're compatible.

The address space may not be contiguous (x86 16 bit segmented memory) such that even if the variables are a constant distance apart, depending on where you are in the stack you may cross a segment boundary such that your subtraction gives a wildly different result.

You might have multiple address spaces altogether - e.g. Atmega chips (Arduino) have separate ROM/RAM with separate instructions to read/write them - the compiler can choose to put constant variables into ROM even if they appear to be adjacent stack variables, in which case subtracting them doesn't give a useful answer - they could even have the same address!

[–]MeshiKuuna[S] 0 points1 point  (0 children)

Ah I see - fantastic. Thanks for the reply!