Earlier quoted context omitted.
> your program has UB it's broken and it doesn't matter if it currently happen to work correct under a specific compiler version, it's also fully your fault Except that compiler writers essentially decide what's UB. Which is a conflict of interest. And they add UB, making previously non-UB code fall under UB. Would you call such code buggy?
If you want a programming language without undefined behaviour, you want something that's not C .
Clang vs. Clang
321–330 of 405 posts
Re: Clang vs. Clang
#322Earlier quoted context omitted.
What languages are suitable for writing algorithms with constant-time guarantees?
According to some comments under this submission, even x86 assembly isn't suitable, or only under specific circumstances that are generally not available in userspace.
Re: Clang vs. Clang
#323Earlier quoted context omitted.
So your issue is not at all any specific thing or action anyone took, but just in general having UB in places not strictly necessary. And "Especially anything [different from The Golden Days]", besides being extremely cliche, is a completely arbitrary cutoff point. A given compiler is free to define specific behavior for UB (and indeed you can add compiler flags to do that for many things); the standard explicitly ac…
Sigh...yes, I don't want any UB where it's not necessary. But if you must have a concrete example, how about realloc? In C89 [1] (page 155), realloc with a 0 size and a non-NULL pointer was defined as free: > If size is zero and ptr is not a null pointer, the object it points to is freed. In C99 [2] (page 314), that sentence was removed, making it undefined behavior when it wasn't before. This is a pure example of be…
I do remember reading somewhere that a real platform in fact not handling size 0 properly (or having explicitly-defined behavior going against what the standard allowed?) being an argument for changing the standard requirement. It's certainly not because compiler developers had big plans for optimizing around it, given that both gcc and clang don't: https://godbolt.org/z/jjcGYsE7W. and I'm pretty sure there's no way this could amount to any optimization on non-extremely-contrived examples anyway.
I had edited one of my parent comments to mention realloc, so if we both landed on the same example, there's probably not that many significant other cases.
Re: Clang vs. Clang
#324Earlier quoted context omitted.
In the context of C++ and STL it is UB. They are in the process of rewording such cases as erroneous instead of UB, but it will take time.
…what’s the difference?
If it's simply erroneous, then it behaves like in every other language outside C and C++: it leaves memory in a bad state if it happens at runtime, but it doesn't have any effect at compile time.
Re: Clang vs. Clang
#325Earlier quoted context omitted.
Sigh...yes, I don't want any UB where it's not necessary. But if you must have a concrete example, how about realloc? In C89 [1] (page 155), realloc with a 0 size and a non-NULL pointer was defined as free: > If size is zero and ptr is not a null pointer, the object it points to is freed. In C99 [2] (page 314), that sentence was removed, making it undefined behavior when it wasn't before. This is a pure example of be…
If SQLite wants exactly C89, it can just require -std=c89, and then people compiling it with a different standard target are to blame. This is just standard backwards incompatibility, nothing about UB (in other languages requiring specific compiler/language versions is routine). Problems would arise even if it was changed from being a defined 'free(x)' to being a defined 'printf("here's the thing you realloc(x,0)'d:…
Backwards compatibility? I thought that was a target for WG14.
> This is just standard backwards incompatibility, nothing about UB
But UB is insidious and can bite you with implicit compiler settings, like the default to C99 or C11.
> whether the C standard should always be backwards compatible is more interesting, but is a question orthogonal to UB
If it's a target, then it should be.
And on the contrary, UB is not orthogonal to backwards compatibility.
Any UB could have been made implementation-defined and still be backwards compatible. But it's backwards-incompatible to make anything UB that wasn't UB. These count as examples of WG14 screwing over its users.
> I do remember some mention somewhere of a real platform in fact not handling size 0 properly being an argument for reducing the standard requirement.
So WG14 just decides to screw over users from other platforms? Just keep it implementation-defined! It already was! And that's still a concession from the pure defined behavior of C89!
> I had edited one of my parent comments to mention realloc, so if we both landed on the same example, there's probably not that many significant other cases.
I beg to differ. Any case where UB was implicit just because it wasn't defined in the standard could have easily been made implementation-defined instead.
Anytime WG14 adds UB that doesn't need to be UB, it is screwing over users.
Re: Clang vs. Clang
#326Earlier quoted context omitted.
The blog post does, at the very end, mention the thing you should actually do . You need a language where you can express what you actually meant, which in this case is "Perform this constant time operation". Having expressed what you meant, now everybody between you and the hardware can co-operate to potentially deliver that. So long as you write C (or C++) you're ruined, you cannot express what you meant, you are s…
> You need a language where you can express what you actually meant, which in this case is "Perform this constant time operation". Having expressed what you meant, now everybody between you and the hardware can co-operate to potentially deliver that. Yeah, even with assembly, your timing guarantees are limited on modern architectures. But if you REALLY need something specific from the machine, that's where you go.
CPUs are actually much better at making those guarantees than compilers are.
Re: Clang vs. Clang
#327Earlier quoted context omitted.
If SQLite wants exactly C89, it can just require -std=c89, and then people compiling it with a different standard target are to blame. This is just standard backwards incompatibility, nothing about UB (in other languages requiring specific compiler/language versions is routine). Problems would arise even if it was changed from being a defined 'free(x)' to being a defined 'printf("here's the thing you realloc(x,0)'d:…
> If SQLite wants exactly C89, it can just require -std=c89, and then people compiling it with a different standard target are to blame. Backwards compatibility? I thought that was a target for WG14. > This is just standard backwards incompatibility, nothing about UB But UB is insidious and can bite you with implicit compiler settings, like the default to C99 or C11. > whether the C standard should always be backward…
C23 removed K&R function declarations. Indeed backwards-compatibility is important for them, but it's not the be-all end-all.
Having a standard state exact possible behavior is meaningless if in practice it isn't followed. And it wasn't just implementation-defined, it had a specific set of options for what it could do.
> Any case where UB was implicit just because it wasn't defined in the standard could have easily been made implementation-defined instead. Any UB could have been made implementation-defined and still be backwards compatible. But anything that wasn't UB that now is counts as an example of WG14 screwing over its users.
If this is such a big issue for you, you could just name another example. It'd take, like, 5 words to say another feature in question unnecessarily changed. I'll happily do the research on how it changed over time.
It's clear that you don't like UB, but I don't think you've said anything more than that. I quite like that my compiler will optimize out dead null comparisons or some check that collapses to a 'a + C1 < a' after inlining/constant propagation. I think it's quite neat that not being able to assume signed wrapping means that one can run sanitizers that warn on such, without heaps of false-positives from people doing wrapping arith with it. If anything, I'd want some unsigned types with no unsigned wrapping (though I'd of course still want some way to do wrapping arith where needed)
Re: Clang vs. Clang
#328Earlier quoted context omitted.
> You need a language where you can express what you actually meant, which in this case is "Perform this constant time operation". Having expressed what you meant, now everybody between you and the hardware can co-operate to potentially deliver that. Yeah, even with assembly, your timing guarantees are limited on modern architectures. But if you REALLY need something specific from the machine, that's where you go.
And besides, Assembly should not be a scary thing. Even most managed languages provide a way to get down into Assembly dumps from their AOT and JIT compiler toolchains. Maybe we need some TikTok videos showing how to do such workflows.
Re: Clang vs. Clang
#329A point of the post that I didn't see discussed here is this: > LLVM 11 tends to take 2x longer to compile code with optimizations, and as a result produces code that runs 10-20% faster (with occasional outliers in either direction), compared to LLVM 2.7 which is more than 10 years old. Yes, C code is expected to benefit less from optimizations, since it is already close to assembly. But compiler optimizations in the…
Rust is possible and proves that you don’t need "optimizations" to optimize, but that optimizations are actually possible. Now that's kind of irrelevent for most of the article focusing about constant versus variable time which is not really an "optimization" problem but already an optimization one, but at least putting appart this rust proves that a langage doesn't need to allow nasal daemons to get good perfs. You…
In particular, however, Rust relies a lot on Undefined Behavior to optimize well. It manages to hide it (mostly) in the surface language, but in the IR they are necessary to perform well.
Re: Clang vs. Clang
#330Earlier quoted context omitted.
> If SQLite wants exactly C89, it can just require -std=c89, and then people compiling it with a different standard target are to blame. Backwards compatibility? I thought that was a target for WG14. > This is just standard backwards incompatibility, nothing about UB But UB is insidious and can bite you with implicit compiler settings, like the default to C99 or C11. > whether the C standard should always be backward…
> Backwards compatibility? I thought that was a target for WG14. C23 removed K&R function declarations. Indeed backwards-compatibility is important for them, but it's not the be-all end-all. Having a standard state exact possible behavior is meaningless if in practice it isn't followed. And it wasn't just implementation-defined, it had a specific set of options for what it could do. > Any case where UB was implicit j…
No, it means that the bug is documented to be in the platform, not the program.
> If this is such a big issue for you, you could just name another example. It'd take, like, 5 words to say another feature in question unnecessarily changed.
Okay, how about `signal()` being called in a multi-threaded program? Why couldn't they define it in C11 such that it could be called? Obviously, such a thing didn't really exist in C99, but it did in POSIX, and in POSIX, it wasn't, and still isn't, undefined. Why couldn't WG14 have simply made it implementation-defined?
> I quite like that my compiler will optimize out dead null comparisons or some check that collapses to a 'a + C1 I'd rather not be forced to be a superhuman programmer.