Live data from Hacker News

PLOS2021: ISO-C became unusable for operating systems

yodaiken.com

51–60 of 100 posts

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

#51

In general I've long been very skeptical of removing optimizations that rely on undefined behavior. People say "I'd happily sacrifice 1% for better theoretical semantics", but theoretical semantics don't pay the bills of compiler writers. Instead, compiler developers are employed by the largest companies, where a 1% win is massive amounts of dollars saved. Any complaint about undefined behavior in C must acknowledge…

> If you want to blame someone, blame the designers of the C language for doing things like making int the natural idiom to iterate over arrays even when size_t would be better. The fact that C programmers continue to write "for (int i = 0; i Well, size_t is unsigned and has defined overflow, so you'd lose the optimization if you switched to it. (Specifically, there's cases where defining overflow means a loop is pos…

There was no size_t in K&R1. Size_t was introduced in the standards process as was the definition of index variables in the for loop. You may have a complain with the standard there.

As for the optimization, it is based on misunderstanding of C semantics. The only place where the sign extend makes a difference is where pointers are longer than "ints" AND where the the iterator can overflow, and in that case, sign extend only makes a difference if the loop is incorrectly coded so that the end condition is never true. The code should just provoke a warning and then omit the sign extend (and it almost certainly doesn't make much of a difference since sign extend is highly optimized and has zero cost in a pipelined processor).

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

#52
post #7
post #4

I think it's about time to abandon C language entirely.

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.

That's a touch unfair.

The problem is that C is sufficiently primitive that optimizing it is effectively trying infer structure backwards because the language doesn't specify it.

For-loops are a great example. Why are we even discussing about a "loop index"? Because we need to iterate over an array, string, etc. and "length" isn't something stored with the data structure so the compiler can't do the loop for you.

The real question is probably more along the lines of "Should the C standard start pinning things down more than it does?"

The answer is probably yes, but it's not straightforward to do. Look at just how much verbiage it took to create a decent memory model. And, still, using atomics in C (as opposed to C++) is brutal and the compiler can't help you very much.

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

#53
post #45

Earlier quoted context omitted.

> template-heavy code results in convoluted IR with tons of unreachable code Does it? Honest question; my impression was that template-heavy code can tend to produce deep call trees, but not necessarily outright unreachable code unless you count instantiations ruled out by SFINAE/std::enable_if/tag dispatching, for which UB-based analyses are not necessary. In addition, I thought template (meta)programming relied ver…

It is quite common for any heavily inlined code to have lots of dead sections. Template code is very frequently heavily inlined. So, it is common for compilers to prune out the dead branches. But C code is often heavily inlined, too, and similarly pruned.

Guess I need to pay more attention to the template code I use. I knew that they tended to rely very heavily on inlining for good performance, but I haven't read as much about the presence/absence of dead code, though to be fair maybe the deadness isn't always obvious to the programmer?

In any case, thanks for correcting me!

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

#54

Earlier quoted context omitted.

> If you want to blame someone, blame the designers of the C language for doing things like making int the natural idiom to iterate over arrays even when size_t would be better. The fact that C programmers continue to write "for (int i = 0; i Well, size_t is unsigned and has defined overflow, so you'd lose the optimization if you switched to it. (Specifically, there's cases where defining overflow means a loop is pos…

The optimization I'm referring to is widening a 32-bit loop IV to 64-bit so it can stay in a register: https://gist.github.com/rygorous/e0f055bfb74e3d5f0af20690759... size_t obviates the need for this optimization.

That's a strange example since it doesn't prove their point.

"int count; … for (int i = 0; i "int count; … for (int i = 0; i I don't think "have a 64-bit int type" is the right approach for a new language either… we should be aiming for safety. If a variable's valid values are 0-50 then its type should be "integer between 0 and 50", not "integer between 0 and UINT64_MAX". Storage size should be an implementation detail.

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

#55

Earlier quoted context omitted.

> If you want to blame someone, blame the designers of the C language for doing things like making int the natural idiom to iterate over arrays even when size_t would be better. The fact that C programmers continue to write "for (int i = 0; i Well, size_t is unsigned and has defined overflow, so you'd lose the optimization if you switched to it. (Specifically, there's cases where defining overflow means a loop is pos…

There was no size_t in K&R1. Size_t was introduced in the standards process as was the definition of index variables in the for loop. You may have a complain with the standard there. As for the optimization, it is based on misunderstanding of C semantics. The only place where the sign extend makes a difference is where pointers are longer than "ints" AND where the the iterator can overflow, and in that case, sign ext…

> There was no size_t in K&R1. Size_t was introduced in the standards process as was the definition of index variables in the for loop. You may have a complain with the standard there.

I certainly do. C and descendants makes you over-specify variables by declaring them all int/size_t/etc individually. It should've had C++11-style "auto" from the start and there should be a statement like "for i=0..n" that declares "i" the same type as "n".

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

#56
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…

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.

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

#57
post #50

Earlier quoted context omitted.

correct. In my experience a focus on UB (often actually said U.B.) tends to come from the C++ community, although a lot of it trickles down to the C community as well. I can recommend watching a few talks from C++ conferences. I especially enjoyed ones by Matt Godbolt, and Miro Knejp.

Not correct. Most UB is the same in C and C++. If you disallowed optimizations based on UB, it might have more effect on C++ programs, just because C++ tends to more deeply inlined abstractions that can benefit more from them. But those don't tend to need much attention. The cases people worry about are more common in C code, just because the concept of type is less important in C.

How is this not correct? UB = Undefined Behavior.

Or are you saying that UB is not from the C++ community? That could certainly be true, I am just describing the situation as I see it where C++ disallows more types of casting or reinterpreting than C does (even if compilers allow it).

One salient example I heard was that the only way to legally read the bits of a float in C++ is to memcpy the float onto an integer type. whereas in C its legal (I believe by using a union).

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

#58
post #4

I think it's about time to abandon C language entirely.

I'm curious what you would replace it with? I can't think of anything actually suitable for most of the low-level operating systems / embedded level things that use C. I know people recommend rust for this kind of thing, but Rust really isn't appropriate in a lot of cases, especially when dealing with microcontrollers not supported by llvm (ie PIC, 8051 off the top of my head). This may be changing, but I was also un…

I'm partial to Forth, but I think "get rid of C" is a bit of an extreme opinion...

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

#59

In general I've long been very skeptical of removing optimizations that rely on undefined behavior. People say "I'd happily sacrifice 1% for better theoretical semantics", but theoretical semantics don't pay the bills of compiler writers. Instead, compiler developers are employed by the largest companies, where a 1% win is massive amounts of dollars saved. Any complaint about undefined behavior in C must acknowledge…

The reason why GCC and LLVM ended up attaining overwhelming market is simply that they produce the fastest possible code No, I think it's more because they are free. In my experience, ICC can be much better at instruction selection while also not being so crazy with exploiting UB.

They also support the widest range of CPU's

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

#60

To me the stupid thing is the abuse of undefined behavior for changing the semantic of the code. The fact that a behavior is not defined in the standard doesn't mean that on a particular hardware platform it doesn't have a particular meaning (and most C programs doesn't need to be portable, since C it's mainly used for embedded these days and thus you are targeting a particular microcontroller/SOC). These optimizatio…

So define the behaviour and get it pushed through the standards committee.

Or even define the behavior and get your compiler writer to implement it.

ps: If I index past the end of the array... what behaviour are you going to define?

Post reply on HN