Live data from Hacker News

PLOS2021: ISO-C became unusable for operating systems

yodaiken.com

71–80 of 100 posts

Re: PLOS2021: ISO-C became unusable for operating systems

#71
post #20
post #3

The fact that a compiler is allowed/encouraged to silently remove whole sections of code because of some obscure factoid is an amazing source of footguns. At least the warnings are getting a bit better for some of these.

Without these optimizations, you can't write fast scientific code in C. This was realized back in the early 1980s and it's why those rules were added. In Fortran the aliasing rules are even stricter: given two arrays passed in as arguments the compiler can assume that they do not overlap, for example. I remember messing that up as a student long ago and getting strange results. The Fortran rule was to enable vectoriz…

Cool, make a sci-C with all the optimisations allowed that is trivially interoperable with simple-C. Mangling the latter into the former serves no-one.

How much slower would removing the UB footgun make scientific code? Do you have benchmarks? Because we have endless firsthand accounts that it makes standard C useless.

Re: PLOS2021: ISO-C became unusable for operating systems

#72

This is a typical whining about UB article, but removing it won't get what you want, in particular your program still won't behave correctly across architectures. Overflow on shift left may be undefined, but how do you want to define it? If you want a "high level assembler", well, the underlying instructions behave differently on ARM, x86 scalar, and x86 SIMD. The reason they claim program optimizations aren't import…

Yes, your program will have different semantics on different architectures. This is already the case with e.g. big vs little endian. But you will be able to reason about the program's semantics rather than going "I sure hope there's no UB in here" and throwing your hands up.

Re: PLOS2021: ISO-C became unusable for operating systems

#73
post #35

Earlier quoted context omitted.

C was always a high-level assembler. UB was meant to be "this cannot be defined portably, refer to your CPU's documentation". What do you gain by making C unusable by default? Just make it 5% slower by default, but possible to reason about and give people the option to shoot themselves in the foot. I don't know what more you need than the creator of the language telling you "this is not possible to implement sanely".

Even assuming the 5% number were correct (depending on how expansive your definition of UB is, it may not be), asking everyone who doesn't adjust their compiler flags to accept a 5% slowdown for some theoretical benefits is at odds with economic reality.

Even assuming the 5% number were correct (depending on how expansive your optimisations with UB assumptions are, it may not be), asking everyone who doesn't adjust their compiler flags to accept their programs being silently miscompiled for some theoretical benefits is at odds with economic reality.

Re: PLOS2021: ISO-C became unusable for operating systems

#74
post #35

Earlier quoted context omitted.

> The compiler should optimize without changing the semantic of the code, even if it contains undefined/unspecified behavior. That is what it does. "Undefined behavior" is a lack of semantics, so it is preserving semantics when it leaves those paths out. You can make a "defined C" with `-fsanitize-trap=undefined`, but C was never a high level assembler, and performance is critical for C users too.

C was always a high-level assembler. UB was meant to be "this cannot be defined portably, refer to your CPU's documentation". What do you gain by making C unusable by default? Just make it 5% slower by default, but possible to reason about and give people the option to shoot themselves in the foot. I don't know what more you need than the creator of the language telling you "this is not possible to implement sanely".

> UB was meant to be "this cannot be defined portably, refer to your CPU's documentation"

You're probably thinking of implementation-defined behaviour, which is the term for behaviour that, although not fully specified by the standard, is a valid behaviour for the program.

Undefined behaviour is different. From the article: "Undefined behavior gives the implementor license not to catch certain program errors that are difficult to diagnose."

Many people don't notice the distinction, and their intuition about what compilers should do with their code matches implementation-defined behaviour; and therefore they complain when, for UB, it does not behave this way.

There is a very strong argument for reclassifying many specific UBs as implementation-defined behaviours, but that's a rather different conversation from "the compiler should always do something sensible when encountering UB".

Re: PLOS2021: ISO-C became unusable for operating systems

#75
A bad workman blames his tools, so they say.

There is a large population of C "real programmers" who, when they write a C program that unsurprisingly doesn't work, conclude this must be somebody else's fault. After all, as a real programmer they certainly meant for their program to work, and so the fact it doesn't can't very well be their fault.

Such programmers tend to favour very terse styles, because if you don't write much then it can't be said to be your fault when, invariably, it doesn't do what you intended. It must instead be somebody else's fault for misunderstanding. The compiler is wrong, the thing you wanted was the obviously and indeed only correct interpretation and the compiler is willfully misinterpreting your program as written.

Such programmers of course don't want an error diagnostic. Their program doesn't have an error, it's correct. The compilers are wrong. Likewise newer better languages are unsuitable because the terse, meaningless programs won't compile in such languages. New languages often demand specificity, the real programmer is obliged to spell out what they meant, which introduces the possibility that they're capable of mistakes because what they meant was plain wrong.

Re: PLOS2021: ISO-C became unusable for operating systems

#76
post #7

Earlier quoted context omitted.

Sometimes I do wonder if all these UB optimisations aren't pushed by people aiming to make C and C++ unusable, so that people will be forced to move to other languages.

It has come to my mind too. It is user hostile none the less, blaming the user for writing incorrect but intuitive code. The Stackoverflow mindset? My favourite is how "x + 1 < x" is optimized away for signed ...

"UB optimizations" happen as a natural consequence of basing optimizations on constraints posed by the language rather than descriptions of special cases. It's not like someone looked at code with signed overflows and decided "let's make this really stupid" and typed "if (MAY_SIGNED_OVERFLOW(expr)) surprise_me();". You might instead specify the constraints of signed integers according to the language spec and a generalized optimizer performs optimizations based on those constraints.

x + 1 That you believe that there is any x for which this would be true is based on assumptions that the C language doesn't make. You likely assume that signed integer arithmetic should be modular as a consequence of its 2's complement bit representation. These are not assumptions that the C language makes. Signed integers don't have to be modular. They don't have to be 2's complement. It might be harder than you think to maintain a set of constraints and assumptions in addition to those specified by the C language. It would be these additions that would be special cases, not the optimizations.

If there's anything you should have a beef with, it's the language itself. Don't use C if you aren't ready to either be caught off guard with unexpected consequences undefined behavior at run time or have the patience to very carefully avoid it by learning what invokes it.

I think much of the "undefinedness" of the language comes from the fact that multiple implementations of the "C language" existed long before standardization. The subtle differences in these implementations and their stake in the standardization process meant that a lot of things simply couldn't be defined because it would invalidate existing implementations.

Re: PLOS2021: ISO-C became unusable for operating systems

#77
post #64

Earlier quoted context omitted.

I doubt that very much, and one of the points of the article is that there is a shortage of data to back up claims like yours. In any case, for people who want to write OS or cryptography or embedded systems or arithmetic libraries or ... in C, this is not a relevant point.

My understanding is the reason FORTRAN is faster than C isn't because of stupid stuff like noalias and the like. It's because FORTRAN has arrays and C doesn't.

Why would that put C at a disadvantage performance-wise? Array decay is, with hindsight, an unfortunate feature, but optimizing access to contiguous memory is very low-hanging fruit as far as compiler optimizations go.

Re: PLOS2021: ISO-C became unusable for operating systems

#78
post #77
post #64

Earlier quoted context omitted.

My understanding is the reason FORTRAN is faster than C isn't because of stupid stuff like noalias and the like. It's because FORTRAN has arrays and C doesn't.

Why would that put C at a disadvantage performance-wise? Array decay is, with hindsight, an unfortunate feature, but optimizing access to contiguous memory is very low-hanging fruit as far as compiler optimizations go.

Some optimizations are low-hanging fruit only if you know length of the array. Which C avoids by design at all costs.

Re: PLOS2021: ISO-C became unusable for operating systems

#79

Earlier quoted context omitted.

It has come to my mind too. It is user hostile none the less, blaming the user for writing incorrect but intuitive code. The Stackoverflow mindset? My favourite is how "x + 1 < x" is optimized away for signed ...

That is the fault of compilers, not the language. That thing should rise at maximum a warning. A compiler should not change the semantic of the code, even if the code relies on undefined/unspecified behavior. I don't get how someone thought that it is a good idea to silently remove apparently unreachable code.

> A compiler should not change the semantic of the code, even if the code relies on undefined/unspecified behavior.

You can argue that there is no semantic of the code if it invokes undefined behavior. What is the correct "semantic" of x+1 if x is the maximum representable value of a signed integer type? The language doesn't specify it, in fact it explicitly calls this undefined behavior; it's absolute nonsense. Should the compiler apply AI to determine the semantic intent?

> I don't get how someone thought that it is a good idea to silently remove apparently unreachable code.

This reminds me of the common misconception of C as a "portable assembly language". The standard is largely machine independent in that it's concerned with the effects of execution rather than how those effects are implemented by the compiler and eventually carried out by a real machine. As a result, you can write several pages of code and have the compiler fold it down into "mov eax, 123 / ret" and nothing that concerns the C language will have been lost.

If you have some expression that correctly folds into "false", none of the effects of the program as far as the C standard is concerned have changed. Yes, some undefined behavior may manifest differently depending on the optimizations made, but the language is not concerned with that.

The problem is very much with the language itself. Overflow in signed integers is undefined behavior. The optimizer correctly won't consider it as a constraint to optimization. The language could as easily have defined signed integer arithmetic as modular. The standard does not have a "compiler should not change the semantic of the code" clause that applies to undefined behavior. As a general rule, the C standard is basically the antithesis to it. The compiler gets free reign over the effects of code where the behavior is undefined by the C standard, which leaves a lot of UB holes.

Re: PLOS2021: ISO-C became unusable for operating systems

#80

A bad workman blames his tools, so they say. There is a large population of C "real programmers" who, when they write a C program that unsurprisingly doesn't work, conclude this must be somebody else's fault. After all, as a real programmer they certainly meant for their program to work, and so the fact it doesn't can't very well be their fault. Such programmers tend to favour very terse styles, because if you don't…

What an unimaginative, dull-witted way to skirt around the concrete criticisms made in TFA.
Post reply on HN