On Fri, May 5, 2017 at 3:23 PM, Bram Moolenaar <[email protected]> wrote: > > James McCoy wrote: > >> Recently, there was some work done on defining how to handle converting >> numeric literals in vim script to C integers -- basically, clamp to the >> extremes of the datatype. If it would exceed the max/min value, then >> just treat it as the max/min value. >> >> However, there's nothing defining how arithmetic behaves when it would >> exceed the range of the datatype. The only information in the help is: >> >> Number A 32 or 64 bit signed number. |expr-number| *Number* >> 64-bit Numbers are available only when compiled with the >> |+num64| feature. >> >> Now, in C signed over/underflow is undefined behavior. If you're "lucky", >> the implementation will wrap but it could just as well optimize the code >> under the assumption that the code can't over/underflow. > > Yeah, I consider this a bug in the C standard. Undefined behavior is > useless, the only reason I suspect this is done is so that compiler > writers can makey the code < 1% faster. And at the same time require > programmers to handle all the edge cases, which gets really complicated > and everybody forgets about. >
There's reasons to want other behavior, and if the standard specified anything in this case it would limit the hardware that compliant C could run on. In almost every case where there is undefined behavior, that previous reason is precisely why it is left unspecified. That most instruction sets and compilers implement wrapping arithmetic is irrelevant - should C implement features that require an IOMMU, just because you're unaware of anybody who would want to avoid the use of one? As an example, saturating arithmetic requires nonwrapping mathematical operations (https://en.wikipedia.org/wiki/Saturation_arithmetic). The SEI CERT C Coding Standard has a section on arithmetic, https://securecoding.cert.org/confluence/pages/viewpage.action?pageId=270, of which rule "INT30-C" is notable: "Ensure that unsigned integer operations do not wrap." There are also algorithms that make use of saturating arithmetic, and numerical methods that might wish to trap on overflow or underflow. It seems to be the vogue for FOSS software authors to have strong opinions, but frankly this one makes you look like an idiot. >> Currently, Vim runs afoul of undefined behavior as can easily be seen >> with a -fsanitize=undefined build by running >> >> if has('num64') >> echo float2nr(pow(2, 62)) * 2 >> else >> echo float2nr(pow(2, 30)) * 2 >> endif >> >> It would be nice for there to be defined behavior here for the user, >> instead of exposing them to the whims of the compiler implementation. > > Unfortunately, that is quite difficult. I propose the compiler standard > gets fixed. This means only the few compilers that exist need to take > care of this, instead of the millions of C programs. > That is never going to happen. The choice here is to either implement correct arithmetic or leave it exposed. Since most people are expecting it it's entirely possible to suggest no action is necessary, but if anyone has the time it would be one of the many steps necessary to making safer and less error prone programs more common. Implementing it is, in theory, easy, as over and underflow can be trapped, but last I checked the support for this in GCC was nonfunctional for some reason. The relevant options are here: https://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Code-Gen-Options.html as "-ftrapv" and "-fwrapv". On most architectures this is implemented as a software trap. The proper way to solve this is in hardware. It's kind of sad, really; the DoD (among other parties) has spent hundreds of thousands of dollars, if not millions of dollars, researching "safe arithmetic" due to faulty hardware implementations. -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
