4 ms·
I have a suggestion - it may be completely off the wall, but hear me out. C needs a mechanism to declare in a source file that certain behaviour must be define
by mnw21cam 4y ago
I have a suggestion - it may be completely off the wall, but hear me out.
C needs a mechanism to declare in a source file that certain behaviour must be defined, where that behaviour is undefined in the C standard but the target architecture behaves the defined way. Then, when the source is compiled on the target architecture it works as expected, but when compiled on something else it refuses to compile.
For example, unsigned ints. It'd be great to be able to declare "I define int to be 32 bits and to overflow like a sensible 32-bit int - treat this as defined behaviour, and refuse to compile on a system where this isn't true." The number of platforms where this would fail to compile would be extremely small, and at least they would give a sensible compile error on systems that are weird.
- yladiz 4y agoI have almost no idea about C compilation but would it be possible with macros or somehow redefining int?
- mnw21cam 4y agoI don't think it'd be possible to get the compiler to treat unsigned integer overflow as defined using macros. But I'm not a subject matter expert.
- variadix 4y agoNot cleanly, but if you assume 2s complement and wrap all signed addition in a macro function you could cast to unsigned before the add and cast the result back to signed.
- obi1kenobi 4y agoSuggestions like this are unfortunately quite infeasible (they fall under the hat of "define all the behaviors"), and the talk I linked in the post goes into why: https://www.youtube.com/watch?v=yG1OZ69H_-o https://www.youtube.com/watch?v=yG1OZ69H_-o (I'm the post's author.)
- naasking 4y agoHe's not trying to define all behaviours, he wants a static assertion that the compiler will compile certain behaviours in a specific way. Seems very different.
- obi1kenobi 4y agoThat's why I said "falls under the hat of" :) I promise the talk is relevant. `-fwrapv` is an attempt toward doing such a thing for signed integer overflow specifically. I bet it's a pain to maintain because it significantly increases the surface area of the compiler that needs to be tested. I don't believe doing this for more cases is feasible at the level of the compiler. Things like CHERI where the hardware and OS help are much more viable, in my book: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/ https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
- sanxiyn 4y agoSigned integer overflow flag is relatively painless to maintain, because compiler needs to be able to track it for unsigned integers anyway. That is, signed integer was modeled with a pair of flags (interpret bits as signed, can't overflow) and unsigned integer (interpret bits as unsigned, wrap on overflow), so signed integer under -fwrapv is just (interpret bits as signed, wrap on overflow).
- dooglius 4y agoI think it's pretty clearly feasible in the specific example GP gave, since -fwrapv does this for GCC and clang. In principle it should be do-able from code level with e.g. 'pragma gcc optimize("frapv")' (but the gcc docs for this say that this feature is for debugging only and doesn't always work).
- Mathnerd314 4y ago"goes into". https://youtu.be/yG1OZ69H_-o?t=1039 https://youtu.be/yG1OZ69H_-o?t=1039 You mean this slide of the Joker with title "Do I really look like the kind of language that would define its behavior?" As far as I can tell there is no reason LLVM couldn't compile a document like "On x86 division by zero throws a #DE exception. On ARM division by zero returns zero. On x86 shifting by more than 32 bits shifts by (cnt mod 32) bits. On ARM shifting by more than 32 bits clears all bits. [...]" that specifies all undefined behavior. The current "nasal demons" behavior is preferred in the name of performance on some SPEC benchmarks that nobody was asking for, screwing OS writers and anyone who expected sane language semantics.
- account42 4y agoThat mechanism exists: inline asm. As for your example, unsigned overflow is already defined in C and C++ and you can force the compiler error for non-32-bits using a static_assert.
- marmetio 4y agoAda already does something like this. You can choose whether to enable runtime checks, fail to compile, or accept the risk. The purpose of C is to be easy to implement on new systems. You're never going to get a lot of traction adding anything to C proper.
- gpderetta 4y ago> Ada already does something like this. You can choose whether to enable runtime checks, fail to compile, or accept the risk. It is ok, the accelerometer readings won't go outside the range of an int.
- marmetio 4y agoI think it's silly to tell people what to do when you don't know what they're doing. For all you know, they could be generating code from a design tool that already does that static analysis. What's nice about Ada is you have choices, and the ecosystem facilitates creating and using such tooling.
- gpderetta 4y agoI wasn't trying to say anything deep. It was just a reference to the Arianne 5 disaster.
- marmetio 4y agoI know what you're referencing, but it's not obvious to people who don't already know about it. And in a way, I think you did say something deep. Web developers often have no idea that problems like this were solved a long time ago, and it lowers their expectations for what should be possible with the tools of their industry.
- Psyladine 4y agoIf the program knew the intention of the programming we wouldn't need programmers to begin with. Undefined behavior may be obvious to the architect but not to the architecture.