Conversation

vitaut 🤍❤️🤍 🇺🇦

I subtracting two null pointers a UB? Asking for a friend.

5
0
0

@vitaut Am I doing it right sir?

$ cat -p test.c
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

int main()
{
    uintptr_t *a = NULL;
    uintptr_t *b = NULL;
    ptrdiff_t c = a - b;
    printf("%td\n", c);
    return 0;
}

$ gcc test.c -Wall -Wextra -pedantic -O0

$ ./a.out
0

Gonna push this to master.

2
0
0

@vitaut

First thing to do is ask at the altar of the conexpr gods: https://godbolt.org/z/67dEq7P4e

next things verify the answer from the one true codex of knowledge: https://eel.is/c++draft/expr.add#5.1

1
0
0
@oleksandr @vitaut IIUC it's UB (depending on how the implemented handles some related constructs)

If you're talking about `NULL - NULL` The C standard allows NULL to be either an integer (in which case subtraction is well defined) or a void pointer (in which case arithmetic is UB).

If you're talking about something like this code snippint, then you hit the "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". It's just "an array", so if they're the same array then it's defined. If they're different then it's UB (as pointer subtraction is only defined for two pointers to the same array).
1
0
0

@vitaut it's UB, see C23 (or at least N3220, I don't have the full standard) 6.5.7p10 "When two pointers are subtracted, both shall point to elements of the same array object, or one past
the last element of the array object". Two null pointers don't point to array objects, so subtracting them is UB. IIRC ubsan will list it as UB if it happens.

2
0
0

@vitaut apparently I stand corrected, as @shafik demonstrated. Or it's different in C and C++

1
0
0

@yrlf @vitaut

To answer C standard question I summon @AaronBallman

0
0
0

@oleksandr Code review: return 0 is redundant otherwise LGTM

0
0
0

@palmer @oleksandr not literally NULLs but pointers that are only known at runtime to be null

1
0
0

vitaut 🤍❤️🤍 🇺🇦

Edited 12 days ago

@yrlf I was also looking at that and was expecting a UB. Maybe there is another piece of wording that makes it not a UB specifically for null pointers.

0
0
0
@vitaut @oleksandr IIUC that's the second case, so it can be UB. I was looking at a C11 draft, seems to the same in the C23 draft. As @shafik points out, it's explicitly defined to be 0 by the C++23 draft.
0
0
1

@vitaut should just result in 0-0 = 0. not really UB. don't we constantly check if (!ptr) everywhere? so a null pointer must be set to zeros or all those nice "checks for null pointers" would be all wrong :)

0
0
0

@vitaut

It is left as an exercise to the reader as to what an appropriate sacrifice for the constexpr gods would be.

0
0
0