Hacker News new | ask | show | jobs
by fluoridation 122 days ago
Some behaviors are left unspecified instead of undefined, which allows each implementation to choose whatever behavior is convenient, such as, as you put it, whatever the hardware does. IIRC this is the case in C for modulo with both negative operands.

I would imagine that the standard writers choose one or the other depending on whether the behavior is useful for optimizations. There's also the matter that if a behavior is currently undefined, it's easy to later on make it unspecified or specified, while if a behavior is unspecified it's more difficult to make it undefined, because you don't know how much code is depending on that behavior.

1 comments

But even integer overflow is undefined.

It's practically impossible to find a program without UB.

I think this is not really true. Or rather, it depends on the UB you are talking about. There is UB which is simply UB because it is out-of-scope for the C standard, and there is UB such as signed integer overflow that can cause issues. It is realistic to deal with the later, e.g. by converting them to traps with a compiler flags.
> I think this is not really true. Or rather, it depends on the UB you are talking about.

I mean, if you're going to argue that a compiler can do anything with any UB, then by all means make that argument.

Otherwise, then no, I don't think it's reasonable for a compiler to cause an infinite loop inside a function simply because that function itself doesn't return a value.

When you say "cause", do you mean insert on purpose, or do you mean cause by accident? I could see the latter happening, for example because the compiler doesn't generate a ret if the non-void function doesn't return anything, so control flow falls through to whatever code happens to be next in memory. I'm not aware of any compiler that does that, but it's something I could see happening, and the developers would have no reason to "fix" it, because it's perfectly up to spec.
According to the author of the second link I gave (here it is again):

https://www.quora.com/What-is-the-most-subtle-bug-you-have-h...

The problem was that the loop itself was altered, rather than that the function returned and then that somehow caused an infinite loop.

> I'm not aware of any compiler that does that, but it's something I could see happening, and the developers would have no reason to "fix" it, because it's perfectly up to spec.

This is where we disagree.

I am not sure what statement you are responding to. I am certainly not arguing that. I disagree with your claim that "it is practically impossible find a program without UB".
A study found that, for a particular subset of UB (code that had legal, detectable behavior changes at differing optimization levels), 40% of Debian Wheezy packages exhibited this UB.

https://people.csail.mit.edu/nickolai/papers/wang-stack.pdf

I submit that that's a small fraction of UB, that much of it would exist at any optimization level.

I know, but this still leaves 60% of programs without such UB which is far from "it is practically impossible find a program without UB". Also this this was a study from 2013 and many of those bugs found were fixed. Also GCC got UBSan in 2013 (so after this study).