Hacker News new | comments | show | ask | jobs | submit login


Fixed by Mark H Weaver, on Fri, 7 Dec 2012.

Avoid signed integer overflow in scm_product

* libguile/numbers.c (scm_product): Avoid signed integer overflow, which modern C compilers are allowed to assume will never happen, thus allowing them to optimize out our overflow checks.

* test-suite/tests/numbers.test (*): Add tests.

A nice example for Regehr's post: C and C++ Aren’t Future Proof


Awesome, I've added a link to the bottom of the post.

Checking for signed overflow by first performing signed overflow is a great C antipattern.

Exactly. I've seen plenty of overflow detection libraries that do precisely this. The undefined overflow plus the lack of access to CPU flags makes a pretty good argument against doing this stuff at the C/C++ level.

Interesting, but given that the code in question computes (expt 2 488) as the square of (expt 2 244), is there actually any way for that bug to cause the observed symptoms?

(2^244 is being shown as zero. 2^488 is being shown as non-zero; presumably the right value though I haven't actually checked. If 2^244 is actually being computed as zero, then unless what's happening somehow depends on the depth of the stack -- surely not possible if this bug is the cause -- 2^488 should be computed as zero squared, which is zero.)

Sure, it's possible. The sequence of multiplications chosen to reach the exponent is different, so these expressions take different paths through scm_integer_expt.

But the sequence of multiplications chosen to reach the exponent isn't different. What the user's expt function does, when asked to compute (expt 2 488), is to compute (expt 2 244) and then square it. When it computes (expt 2 244) it does the exact same sequence of multiplications as if you just asked for that directly from the REPL.

What am I missing here?

I currently think the C compiler vendors have gone too far with this.

Although the specification says this behaviour is undefined in practice I used to map the undefined portion to being whatever my hardware did, not whatever the compiler felt like this week.

This ruins the C as a portable assembler use case and means if I was doing this sort of work I'd probably write these sort of routines in assembler rather than trying to fight with versions of C compiler.

...how was C "portable" assembler if its semantics depended on the underlying hardware? That's by definition unportable.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact