Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

321–330 of 503 posts

Re: Undefined behavior in C is a reading error

#321
post #163

Earlier quoted context omitted.

The current situation is not good for compiler writers either. But nobody has ever shown that either C programmers want to sacrifice safety for "optimizations", or that these UB optimizations actually improve performance of anything.

What do you mean by "these UB optimizations"? C is a low-level language; it's basically impossible for a compiler to reason about the code unless it makes certain assumptions. It needs to assume the code is not self-modifying to do pretty much any code-generation more intelligent than a macro assembler. It needs to assume the code isn't messing with the stack frames/return addresses in order to inline functions. It n…

> most compilers provide a choice (-fwrapv, -fno-strict-aliasing, ...). Yet few projects use these options,

Even if you opt into those (and the projects I've been involved with have), the precedent is established: when new compiler optimizations are introduced with disruptive semantics, they are opt-out, not opt-in — a fail-dangerous failure mode.

> Doesn't that indicate that C programmers indeed want to sacrifice safety for optimizations?

Maybe so. Which is one reason I wouldn't call myself a "C programmer" any more. The demands to program responsibly in C are absurdly high.

Re: Undefined behavior in C is a reading error

#322
post #127
post #95

Earlier quoted context omitted.

It's not so much about cleverness, but knowledge and vigilance. You first have to be aware of all the footguns, and then be careful not to let any of them slip through...

> You first have to be aware of all the footguns, Knowing your tools is part of being a professional. C is not for amateurs.

A true mark of a professional is being deathly terrified of the footguns that you must nevertheless use as tools.

Re: Undefined behavior in C is a reading error

#323
post #113

Earlier quoted context omitted.

> If, instead, we force compilers to think about the fact that offset + 16 could have some implementation-defined meaning like wrapping, then all bets are off & we have to throw a bunch of optimization opportunities out the window. Uh huh. If `i` is declared as `unsigned int` instead of `int`, then overflow is defined and the compiler can't apply those optimizations. And yet the world doesn't end and the sun will sti…

The world doesn't end, but in the "int" case you get nice vector code and in the "unsigned int" case you get much less nice scalar code: https://gcc.godbolt.org/z/cje6naYP4

Clang uses vectors for both. https://gcc.godbolt.org/z/G997Ge9KT

Re: Undefined behavior in C is a reading error

#324
post #282

Earlier quoted context omitted.

This is actually desired though, at least by some programs. For example, say you have a function with a very expensive loop that repeatedly performs a null check and then executes some extra code if it's null, but never sets the value. This is called from another function which uses the checked value without a null check (proving it's not null) before and after the loop ends. The first function is inlined. You want t…

There may be programs that desire such behavior. But I've never intentionally written one. Which is why I personally avoid C, and wish that I didn't have to work in environments coded in C. I seriously would accept everything running at half speed for the certainty of not being subject to the problems of C level bugs. But as Rust grows in popularity, it looks like I won't need to worry about that.

> I seriously would accept everything running at half speed for the certainty of not being subject to the problems of C level bugs.

I think most people would. But the described code is still buggy even when it's not optimized.

Re: Undefined behavior in C is a reading error

#325

Earlier quoted context omitted.

> minority use-case The amount of code that looks like this in a big enough hot loop to make a difference is negligible. Can you provide even one real-world example where this makes a difference, i.e. not some microbenchmark? The amount of code that can break as a result of signed overflows being UB, on the other hand, is huge. > programmers would have to do a lot more fragile hand-unrolling of operations to get that…

> Can you provide even one real-world example where this makes a difference, i.e. not some microbenchmark Sure. I don't even have to leave this thread to find one: https://news.ycombinator.com/item?id=27223954 reports a measurable speed impact to PostgreSQL when compiled with -fwrapv, which rules out the exact optimization in question. This shouldn't be surprising; loops are extremely common and superscalar processor…

Sure, if you leave out error checks code runs faster. Compile mutexes to no-ops and get an even better speedup.

Re: Undefined behavior in C is a reading error

#326

Earlier quoted context omitted.

For your last point, the extent of UB driven changes to semantics is still not widely known in the programmer community. Programmers don't read the standard - they read K&R, and K&R is right now describing a different language. We've had 15 years of programmers repeatedly filing bug reports to be told that the expected, tested, relied on, behavior was ephemeral. Only very sophisticated projects figure out about UB. O…

So what optimizations do you mean with "these UB optimizations" then? And would it change your mind to see a benchmark proving the usefulness of that particular UB optimization?

> So what optimizations do you mean with "these UB optimizations" then?

Inferring any propositional statement about the program (eg "this pointer is not null") from the fact that its negation would imply undefined behaviour.

Re: Undefined behavior in C is a reading error

#327
post #61
post #24

I think the real problem stems from the mismatch between modern processors and the processors C was originally designed for. C programmers want their code to be fast. Vanilla C no longer gives them the tools to do that on a modern processor. Either the language needs to be extended or the compiler needs to get more creative in interpreting the existing language. The latter is the least disruptive and it doesn't stop…

Even on modern processors, an ADD instruction does not corrupt memory. The C standard, in declaring that an integer overflow results in all-bets-are-off UB, is not enabling compilers to provide valuable optimizations.

There is no guarantee that an addition in C is even going to convert into an add instruction, though. Actually, on x86 it's more likely to turn into a lea because this optimizes port usage better.

Re: Undefined behavior in C is a reading error

#328

Earlier quoted context omitted.

More than slightly convoluted. The obvious intention is that the compiler ignores overflow and lets the processor architecture make the decision. Assuming that overflow doesn't happen is assuming something false. There's no excuse for that and it doesn't "optimize" anything.

> The obvious intention is that the compiler ignores overflow and lets the processor architecture make the decision. If that were the case, wouldn't signed overflow be implementation-defined or unspecified behavior, instead of undefined behavior? > Assuming that overflow doesn't happen is assuming something false. It's "false" in the same way that assuming two restrict pointers don't alias is "false". It may not be u…

[deleted]

Re: Undefined behavior in C is a reading error

#329

Earlier quoted context omitted.

> extremely rare in the code I see Well, I learned of the change in compiler behavior some years back because I had written loop code with a sanity check which depended on signed integer overflow wrapping, along with a test case to prove that the sanity check worked, and that test case started failing: not ok 2 - catch overflow in token position calculation Failed test 'catch overflow in token position calculation' a…

> people who think that silently optimizing away previously functional sanity checks is an acceptable engineering tradeoff To be fair, as several people and TFA have pointed out, this isn't a problem with C, but with defective/malicous C compilers . Admittedly, that's not much help if you can't find a compiler that isn't defective/malicous, though, so I can only wish you the best of luck.

I don't get what you or the comment you're responding to are wishing for.

Do you want compilers to stop adding optimizations while staying within the bounds defined by the spec? That they somehow guess that a given piece of code that may trigger UB is too important for them to optimize it based on the assumption that the developer knew what she was doing and ensured that it wouldn't?

The case of a compiler update breaking the test sounds like desirable to me. It pinpoints a critical piece of code that was relying on a specific implementation's behavior that is not specified. This could have been triggered by a compiler or architecture change. If this is something that is a hassle to fix immediately, you can temporarily downgrade to the version of the compiler used earlier or disable some optimizations.

I fail to see why one would consider a compiler evolving while conforming to language specification defective or malicious (however, with that definition I fear that finding one that isn't may indeed be difficult).

Re: Undefined behavior in C is a reading error

#330

True story -- someone (not me) decided to initialize a C++ virtual class by defining a default ctor which does a "memset(this, 0, sizeof(*this))", then uses placement new to re-create the vptr. Newer compilers complained more and more until gcc 8 which just silently ignored this awful hack -- no diagnostic, no error, just crickets. Strictly speaking silently ignoring this atrocity is allowed by the standard, but it s…

Perhaps you should file a bug to make them bring back the warning.
Post reply on HN