Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Let's not vague post on HN. What's the problem with the above?
 help



The 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.

But if the assertion fails, the program is aborted before the pointer would have been dereferenced, making it not UB. This explanation is bogus.

Only if the assert is active. It basically means that the code is invalid when NDEBUG is set.

When 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.

> 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.

> 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=63...


No, 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.

> 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?


No, the code that does this is always active

Right 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

> 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.


Shouldn'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]].

Sorry, yes, I misread you



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: