<div dir="ltr"><div><div><div>Undefined behaviour is not guaranteed to cause a
stop. It's just "do something that may or may not be what you expected".
Yes, most operating systems prevent NULL accesses, and cause the
application to crash, but it's by no means guaranteed.<br><br>My worry is that you'll potentially get very weird crashes in systems where `nullptr` isn't a location that is prevented from executing. I've accidentally hit this with kernel mode drivers, where something has actually mapped address zero as a valid address - and then you scratch your head A LOT for the case where it is executing at address 0x43, and trying to access some random location you can't use (or invalid instruction, or whatever it may be). <br><br>The only worse bug to understand was when I accidentally overwrote the entire code up to the point where the memset was looping at - but after the second or third time I managed to forget to include the string.h [which in that environment reversed the order of the address and size, so I'd fill from size, address number of bytes - size typically being small, and address much larger -> filling all over the place], I learned to recognise the pattern. <br><br>Both cases cause "What the heck is going on here" type situations - even with good debug tools like in circuit emulators or external debgugers, it's even worse if you only have regular debugger (or only "printf", "blink the LED" etc)<br><br></div>Certainly in a debug build, I'd add an assert for `fn != nullptr` in the `Go` function. Possibly even actively prevent it from getting through in release builds - presumably the `SomeFunction` is more than a few instructions anyway.<br></div><br>--<br></div>Mats<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 14 June 2016 at 05:07, Gor Nishanov via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all:<br>
<br>
This question is related to a state machine generated by LLVM for a coroutine.<br>
I stripped all coroutine related details to get to the essence of the question.<br>
<br>
Let's say I have a state machine that looks like this:<br>
<br>
struct State {<br>
FnPtr Fn;<br>
State() : Fn(&SomeFunction) {}<br>
<br>
void Go() { (*Fn)(); }<br>
void Stop() { Fn = nullptr; }<br>
bool IsDone() { return Fn == nullptr; }<br>
};<br>
<br>
Fn field serves two purposes:<br>
<br>
* Cheap check for done. What can be better than compare with zero!<br>
* Guard against programmer mistake: accidentally calling Go() when in a<br>
Stopped state.<br>
<br>
Is it an appropriate use of undefined behavior?<br>
<br>
Thank you,<br>
Gor<br>
<br>
P.S.<br>
<br>
This iassumes -O3 with no ubsan. Sanitizer can, of course, add a null<br>
check in Go() prior to an indirect call.<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div>