Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

81–90 of 503 posts

Re: Undefined behavior in C is a reading error

#81
post #78

Earlier quoted context omitted.

> For example, if signed integer overflow yielded an unspecified result rather than causing undefined behavior, I wonder if any implementations would be adversely affected. I suspect so - makes it harder to reason about loop counts because the compiler can't necessarily guarantee that an incremented loop counter won't become negative and thus the loop needs to iterate more. E.g. something like for (int i=param; i Tha…

> I suspect so - makes it harder to reason about loop counts because the compiler can't necessarily guarantee that an incremented loop counter won't become negative and thus the loop needs to iterate more. This is a favourite example that gets thrown around, but for all practical loops GCC and clang seem to have no problem even when you compile with -fwrapv

Postgres compiles with fwrapv for many years now, and yes, it does introduce a measurable CPU overhead. Not 10%, but also not just 0.1%.

Re: Undefined behavior in C is a reading error

#82
post #31

The author suggests that the text following the definition of "undefined behavior", listing the permitted or possible range of undefined behavior, should be read to restrict the consequences. But the first possibility listed is "ignoring the situation completely with unpredictable results". Surely that covers any possible consequences. The author also says: > Returning a pointer to indeterminate value data, surely a…

Unspecified result means the compiler must think about what could happen in case I made an error.

UB means the compiler will trust me and concentrate on generate the fastest code ever.

C is for clever programmers; if you don't want to be clever, you are free to use Go or something like that.

Re: Undefined behavior in C is a reading error

#83

It's easy to pick on undefined behavior in C when you focus on the more gratuitous undefined behaviors such as signed overflow or oversized shifts. I'm not certain why these are undefined behavior instead of implementation-defined, but my suspicion is that these caused traps on some processors, and traps are inherently undefined behavior. Instead, if you dislike undefined behavior, I challenge you to come up with wor…

> It's easy to pick on undefined behavior in C when you focus on the more gratuitous undefined behaviors ...

That is the whole point. There are scores of instances of gratuituous UB.

> I'm not certain why these are undefined behavior instead of implementation-defined, but my suspicion is that these caused traps on some processors, and traps are inherently undefined behavior.

Traps are not inherently undefined. The C standard discusses floating point traps in detail. Many details may of course be left to the implementation or platform to describe, but that's very different from saying "all bets are off".

The real reason for the gratuitous UB was misunderstanding and ignorance.

> Hopefully, you'll agree that that is a reasonable optimization.

Hopefully, you'll agree that the code is buggy, and should be fixed. We end up running expensive and cumbersome static analysis tools that try to detect situations just like this ... which the compiler itself has detected, but chosen not to warn us.

Re: Undefined behavior in C is a reading error

#84
post #73

I think the problem is cultural in the C community. C programmers have Stockholm Syndrome around UB optimizations. As TFA notes, "There is No Reliable Way to Determine if a Large Codebase Contains Undefined Behavior" https://blog.llvm.org/2011/05/what-every-c-programmer-should... That's because UB is a bug that occurs as your program runs (e.g. dereferencing a null pointer). You'd have to prove that your program is f…

> But C programmers believe they deserve to be abused this way. I don't know of any C programmers who think that way. We accept the state of affairs because there is little alternative. We're not going to rewrite our code in another language, because we mostly need to write in C for various reasons. Also Rust inherits LLVM's undefined behaviour, so it's no panacea. We mostly keep adding flags to turn off the most exc…

Rust inheriting it is the equivalent of a codegen bug, and they get patched. The cause here isn’t LLVM, it’s language semantics.

Re: Undefined behavior in C is a reading error

#85
post #48

Earlier quoted context omitted.

I'm not sure why syscalls would be UB; it's just not something defined by the C standard. Edit: To clarify, I meant UB in the sense it is typically used in these discussions, where the standard more-or-less explicitly says "If you do X, the behavior is undefined." Not in the literal sense of "ISO C does not say anything about write(2), hence using write(2) is undefined behavior according to the C standard", which see…

What do you think UB is if not something where the behaviour is not defined?

UB, in this context, is very explicitly used in the standard: it is undefined behavior related to a construct that the standard describes.

Re: Undefined behavior in C is a reading error

#86
post #46

I'm afraid the author themselves is misreading the definition of undefined behavior. Undefined behavior is not "behavior upon use of a nonportable or erroneous program construct". That rephrasing completely changed the meaning. Undefined behavior is, as the C standard states, "behavior [, ...,] for which the Standard imposes no requirements". The whole ", upon use of...," part is just exemplifying situations in which…

True. I think the point of the author is that the C standards group is not doing their job by leaving so much room for compilers to interpret undefined behavior.

Re: Undefined behavior in C is a reading error

#87

Commenters here seem to be missing the core thesis of this article. It's not about what the standard literally means; it's about it's spirit -- and the reason for its spirit. The issue is "undefined behaviour" should never have been interpreted this extremely. The standard may be silent on how extreme, but it is implausible to suggest that the standard was actually written to enable this. Compiler writers for C! dism…

Personally, I think that arguing that those who define and implement a standard don’t understand one of the most fundamental aspects of said standard is going to be an uphill battle.

You could argue that they’ve lost their way, and the article flirts with this, but the path forward is the hard part, and IMHO rings a bit hollow: it’s asserted that these rules aren’t needed for performance, but no evidence is given, and what similar evidence we do have (compiling on lower optimization levels) doesn’t seem to support this thesis. You could argue that, the kernel, which turns off aliasing, is plenty performant without it, and that’s a decent argument, but it’s not clear that it wouldn’t be even faster with it, and it’s much harder to empirically test this than removing the flag, since it will miscompile.

Re: Undefined behavior in C is a reading error

#88
post #77

I'm not convinced. The argument seems to hinge to a very large extent on the sentence: > Permissible undefined behavior ranges from A, to B, to C. The observation that "Permissible" has a specific meaning is important and interesting. But what about "ranges from ... to ..."? The author reads this as "Permissible undefined behavior is either A or B or C.", but that seems like a stretch to me. (Unless ISO defines "rang…

>Somehow the author seems to think that this is not what the wording intended, but they also fail to explain what they think should happen here. What "should" happen is that the implementation-defined behavior in the assert matches the implementation-defined behavior in the calculation. That is, assert(a+100>a) should produce the same result as int x = a + 100; int y = a; if (x > y) ; else printf("assertion failed\n"…

That behaviour is no less undefined in the process of overflow.

Re: Undefined behavior in C is a reading error

#89
Reading error or not, the ship has sailed long ago. As the article notes, C99 formalized the current UB interpretation. What C89 or K&R said is more just historical curiosity than of any real relevance today. I guess you could construct an argument that gcc should disable some optimizations when invoked with -std=c89, but I doubt anyone really cares at this point enough to justify the maintenance burden.

C is a minefield today, and that is the reality we must live with. You can't turn back time 25 years and change what has happened.

Re: Undefined behavior in C is a reading error

#90
post #42

> license for the kinds of dramatic and unintuitive transformations we’ve seen from the compilers, and any indication that undefined behavior should be a vehicle for permitting optimizations. Does anyone have an example of a time where Clang or GCC actually did something bad upon witnessing undefined behavior, rather than simply doing nothing, as the standard proposes? I ask because every time I've seen people get ma…

This may not necessarily count as an example in the wild, but the 2013 Underhanded C contest at http://www.underhanded-c.org/_page_id_25.html includes this example:

  h = abs(h) % HASHSIZE;
  // Extra sanity check
  if (h = HASHSIZE)
    h = 0;
  return h;
where h=INT_MIN causes the h to become negative and the sanity check is optimized out because abs(INT_MIN) is UB.
Post reply on HN