3 ms·
Let's not vague post on HN. What's the problem with the above?
by secondcoming 6mo ago
Let's not vague post on HN. What's the problem with the above?
- saagarjha 6mo agoThe problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. This means it is legal to optimize out any code paths that rely on this, even if they occur earlier in program order.
- aw1621107 6mo ago> The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. Only when NDEBUG is defined, right?
- saagarjha 6mo agoNo, the code that does this is always active
- gottheUIblues 6mo agoRight so strictly speaking C++ could do anything here when passed a null pointer, because even though assert terminates the program, the C++ compiler cannot see that, and there is then undefined behaviour in that case
- aw1621107 6mo ago> because even though assert terminates the program, the C++ compiler cannot see that I think it should be able to. I'm pretty sure assert is defined to call abort when triggered and abort is tagged with [[noreturn]], so the compiler knows control flow isn't coming back.
- aw1621107 6mo agoShouldn't control flow diverge if the assert is triggered when NDEBUG is not defined? Pretty sure assert is defined to call abort when triggered and that is tagged [[noreturn]].
- saagarjha 6mo agoSorry, yes, I misread you
- pwdisswordfishy 6mo agoBut if the assertion fails, the program is aborted before the pointer would have been dereferenced, making it not UB. This explanation is bogus.
- saagarjha 6mo agoOnly if the assert is active. It basically means that the code is invalid when NDEBUG is set.
- quuxplusone 6mo agoWhen NDEBUG is set, there is no test, no assertion, at all. So yes, this code has UB if you set NDEBUG and then pass it a null pointer — but that's obvious. The code does exactly what it looks like it does; there's no tricks or time travel hiding here.
- teo_zero 6mo ago> it is legal to optimize out any code paths that rely on this, even if they occur earlier in program order. I don't think this is true. The compiler cannot remove or reorder instructions that have a visible effect. if (p == 0) printf("Ready?\n"); *p++; The printf() can't be omitted.
- aw1621107 6mo ago> The compiler cannot remove or reorder instructions that have a visible effect. You might be surprised! When it comes to UB compilers can and do reorder/eliminate instructions with side effects, resulting in "time travel" [0]. IIRC the upcoming version of the C standard bans this behavior, but the C++ standard still allows it (for now, at least). [0]: https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633 https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...
- saagarjha 6mo agoNo, this is explicitly legal. Most compilers will shy away from it these days since it made a lot of people upset, but it's definitely allowed.