3 ms·
> Imagine this code...In a world where you can't optimize based on UB assumptions, x can change in the body of f. Yeah, so you allocate space on the stack (whi
by gavinhoward 3y ago
> Imagine this code...In a world where you can't optimize based on UB assumptions, x can change in the body of f.
Yeah, so you allocate space on the stack (which is free, by the way, because space has to be allocated anyway for the new function's frame), store to it, and load from it.
An extra store and an extra load. Of stack space that was probably already in cache anyway.
So what? What a miniscule price to pay. [0]
> You don't need to share memory across threads to opt in to data races. You can access whatever you want with pointer arithmetic if you want to be correct in the presence of UB.
So C should have bounds checks and define a failing bounds check as an abort. And then such optimizations could be correct. That's what so many other languages do, and it works.
> Or this code...f could be deleted. This could be UB.
Do you mean freed?
Yes, that could be UB. But the compiler should never say, "Oh, well, f could be freed here, so I'm just going to delete the `f->do()` call."
Bad example because compilers don't currently take advantage of it. They day they take advantage of that is the day that I quit programming.
> I do not believe this. I am one of the people at my company fighting to spend performance to buy safety.
Ha! I do not believe you at all! You are okay with compilers taking advantage of UB to elide a store and a load.
The only way you are telling the truth is if your company is full of malicious compiler authors.
> I just don't believe that the principle of least surprise can be implemented in the standard in the way some people say
It totally could. C could even have bounds checks without changing the ABI. They just don't.
> I don't believe that UB is totally unique from other forms of incorrectness in a way that should cause us to behave very differently about it.
It's the only form of incorrectness that:
* Will destroy everything.
* That compiler authors claim they have a right to take advantage of.
Yeah, we definitely should treat it differently. You are dead wrong.
> Do you run your production binaries with all of the sanitizers enabled?
No, because I don't work in the industry.
But in my personal code, I wrote my own bounds checks and enabled them. In C. In release mode. All your talk of "but you could make a pointer to anywhere" doesn't happen in my code.
I use structured concurrency to allocate and free items in only one place, in the same stack frame. When threads are created, they prevent the creating thread from returning from the stack frames that the children may have gotten pointers to.
I fuzz like you wouldn't believe and make sure all paths come back clean in ASan, UBSan, TSan, and Valgrind, including memory leaks.
I add all unique paths from fuzzing to my test suite.
I'm going to write my own malloc() that will have double-free and use-after-free checks.
I use unsigned types to avoid signed overflow, and such unsigned types more easily trip the bounds checks when they overflow because the bounds checks only need one condition.
Tell you what: I would like you to take version 6.7.2 of my bc [1] and get it to execute UB. Any UB is fine.
If you do, I'll enable sanitizers on my release builds of all of my software.
But you won't, and that's why I can forego sanitizers on release builds: I do enough work to ensure that UB won't happen.
And that's why I use unsigned types. Your bellyaching about their poor optimization will not change that.
[0]: https://gavinhoward.com/2023/10/he-who-gives-up-correctness-for-performance-deserves-neither/ https://gavinhoward.com/2023/10/he-who-gives-up-correctness-...
[1]: https://git.gavinhoward.com/gavin/bc https://git.gavinhoward.com/gavin/bc
- UncleMeat 3y agoIf your code is so flawless to be free of any and all UB, why are you mad at the compiler? You are the one spending overhead for nothing. You'd be the leaving data dependencies that fuck up speculation all over the place.
- gavinhoward 3y agoOnce again, you focus solely on performance. This is why I don't believe you care about correctness. But to answer your question, because the malicious compiler doubled the work I had to go to get to this point. Or worse. Maybe it increased the work by an order of magnitude. In addition, the checks are what prevent UB, especially the kind where you claim that any pointer anywhere can mess up everything. It's not UB if the behavior is defined as a crash before anything bad happens. And to answer your complaint that I'm leaving performance on the table, so what? Sure, I'm "messing" with speculation (though not by much because I tell the compiler that the error branch is unlikely to be taken), but Spectre and Meltdown showed that maybe speculation was a bad thing. By the way, in my bc, I actually turn a lot of checks off, the checks for which I am 10 9's sure there aren't problems. Not an exaggeration, by the way; I've run my bc under a fuzzer for probably 50 billion executions or more. And every single one of the paths were fixed until they came out clean in the sanitizers and Valgrind. Even across the entire world, I doubt my bc has run 50 billion unique executions; most of the time, people run it on the same scripts with similar data, over and over. In my other project, I don't turn off checks because it hasn't seen that level of testing. That's why I said you could attack bc; checks will actually be off. Make sure you do it in release mode, though if you get an assert to trigger in debug mode first, that same input should also cause UB in release mode. Have fun. I'm done. Contact my through my bio if you succeed.
- UncleMeat 3y ago> Once again, you focus solely on performance. This is why I don't believe you care about correctness. And once again, you are making false statements about me. In fact, I am one of the people the performance folks are mad at because I'm fighting to buy safety. It is just impossible to do this when the conversation is so poisoned by arguments like yours. This is exactly the sort of communication that makes it so difficult to make meaningful progress on this problem. People just calling other people stupid idiots who don't care about correctness. People need to be precise in what they are asking for from the compilers and the committees and honest about what it costs. That is all I am asking.