I’m quite sure this question has been asked before, but I just couldn’t find it.
If I have a pointer that is null, e.g. a char* initialized to nullptr, is it undefined behavior (UB) to add 0 to it? I haven’t actually found any claim that adding anything to a null pointer is UB, but I’d guess adding anything except 0 for sure is UB.
char* buf = nullptr;
buf += 0; // UB?
This is of course not my actual code, but I have pointer–length pairs that could end up (nullptr, 0). Some functions modify this pair without dereferencing the pointer and could end up adding 0 to a null pointer. Do I need to protect these by an if (ptr != nullptr) or would that be wasted lines of code?
I know that executing UB leads to a compile error in constexpr evaluation, so I tried this:
static_assert([](char* buf){ buf += 0; return buf == nullptr; }(nullptr) == true);
static_assert([](char* buf){ buf += 1; return buf == nullptr; }(nullptr) == false);
The latter fails to compile (messages below) because I add 1 to a null pointer (as expected), but the first static_assert is fine on all compilers I tried (GCC 12.1.0, Clang 15.0.0, and MSVC 19.34.31942). Does this mean that it is in fact not UB to add 0 to a null pointer or does it only prove that it is defined in those compilers?
Messages:
- GCC: “arithmetic involving a null pointer”
- Clang: “cannot perform pointer arithmetic on null pointer”
- MSVC build: “failure was caused by unevaluable pointer value”
- MSVC IntelliSense: “invalid arithmetic on non-array pointer”