Live data from Hacker News

Modern C (2019)

gustedt.gitlabpages.inria.fr

21–30 of 57 posts

Re: Modern C (2019)

#22

It looks like an introductory C programming book. I was hoping for it to be a "hello experienced C programmer, here's new stuff that's happened in the past 20 years" kind of thing which would be useful. I think most people have a hard time keeping up with the progress of all the technologies they use unless they've got a pretty narrow focus. For instance, I learned make in the 90s. I should probably go read up on wha…

There are some good books to give you that kind of delta for C++11/14/17/20.

  Modern C++ for Absolute Beginners
  Modern C++ Programming Cookbook
  et al.
I'm actually starting to like C++ again. Weird.

Re: Modern C (2019)

#23
post #18

Earlier quoted context omitted.

How is this UB? foo() won't have any access to y so won't be able to modify it, so we can be more or less certain that y is still 42 when bar() is called? What is it that i'm missing?

That's it -- the optimization is legal because there's no way foo() could modify y, because any (&x)[1] = 20 shenanigans would be UB. This is how UB is used in optimizations; it's (usually) not that the compiler is finding positions where UB occurs and explicitly choosing to perform mischief, it's performing a bunch of simple and obviously-what-you-want rewrites that are only correct because of UB; otherwise, arbitra…

UB is what allows `(&x)[1]` to happen at all. If you didn't have UB, there would be no reasonable way to allow code that messes up arbitrary pointers.

A typical non-UB language wouldn't allow `(&x)[1]` and it would be easy to allow the optimization.

It would be difficult or obtuse to design a non-UB language that doesn't allow optimizing y away.

Re: Modern C (2019)

#24

Earlier quoted context omitted.

Y is never visible from foo()s scope. You'd have to employ ABI specific stack manipulation to get to it. Optimization in the outside frame doesn't depend on foo().

And that ABI specific stack manipulation would be UB, so the optimizer can assume it doesn't happen. With no UB, that's not true.

You assume a langue without UB would allow stack manipulation. But then it would have to be defined. How would you possibly define it fully?

Re: Modern C (2019)

#25
post #9

Earlier quoted context omitted.

Should a compiler be allowed to optimize: int x = 0; int y = 42; foo(&x); bar(y); to: int x = 0; foo(&x); bar(42); without performing analysis on foo? If so, how can that optimization be legal without UB?

How is this UB? foo() won't have any access to y so won't be able to modify it, so we can be more or less certain that y is still 42 when bar() is called? What is it that i'm missing?

The biggest misunderstanding people have around UB is—in my experience—the (often) subconscious assumption that UB optimization is around optimizing the performance of code that exhibits UB. It is not.

You're partially correct. foo() won't have any access to y so won't be able to modify it… unless foo() is written in way that exploits undefined behavior. Compilers can (and should) assume that foo() is not written pathologically in a way that writes into the frames of functions higher in the call stack, and so can make the above optimization.

Re: Modern C (2019)

#26
post #18

Earlier quoted context omitted.

That's it -- the optimization is legal because there's no way foo() could modify y, because any (&x)[1] = 20 shenanigans would be UB. This is how UB is used in optimizations; it's (usually) not that the compiler is finding positions where UB occurs and explicitly choosing to perform mischief, it's performing a bunch of simple and obviously-what-you-want rewrites that are only correct because of UB; otherwise, arbitra…

UB is what allows `(&x)[1]` to happen at all. If you didn't have UB, there would be no reasonable way to allow code that messes up arbitrary pointers. A typical non-UB language wouldn't allow `(&x)[1]` and it would be easy to allow the optimization. It would be difficult or obtuse to design a non-UB language that doesn't allow optimizing y away.

Standard Forth, to my knowledge, doesn't have UB and consequently doesn't allow the optimization. That'd just be

    : foo CELL + 20 SWAP ! ;
there. Machine languages also generally don't have this kind of UB, and don't allow the optimization.

It's not impossible to imagine a C without UB, it's just not a particularly desirable language.

Re: Modern C (2019)

#27
post #4

Earlier quoted context omitted.

C biggest "mistake" (there are historical reasons for this, though, but it doesn't make it acceptable nowadays) is the concept of undefined behavior, period.

I'm okay with undefined behavior, but the language should revert back to the original (an exhaustive list of permissible behavior by the host when the C abstract machine's behavior is undefined) rather than the current mere list of examples of possible behavior by the host.

"I'm okay with undefined behavior, as long as its behavior is well-defined."

You keep using that word. I don't think it means what you think it means. :)

Re: Modern C (2019)

#28

It looks like an introductory C programming book. I was hoping for it to be a "hello experienced C programmer, here's new stuff that's happened in the past 20 years" kind of thing which would be useful. I think most people have a hard time keeping up with the progress of all the technologies they use unless they've got a pretty narrow focus. For instance, I learned make in the 90s. I should probably go read up on wha…

"21st Century C" by Klemens (2014) fills that niche: https://www.amazon.com/21st-Century-Tips-New-School/dp/14919...

Re: Modern C (2019)

#29
post #26

Earlier quoted context omitted.

UB is what allows `(&x)[1]` to happen at all. If you didn't have UB, there would be no reasonable way to allow code that messes up arbitrary pointers. A typical non-UB language wouldn't allow `(&x)[1]` and it would be easy to allow the optimization. It would be difficult or obtuse to design a non-UB language that doesn't allow optimizing y away.

Standard Forth, to my knowledge, doesn't have UB and consequently doesn't allow the optimization. That'd just be : foo CELL + 20 SWAP ! ; there. Machine languages also generally don't have this kind of UB, and don't allow the optimization. It's not impossible to imagine a C without UB, it's just not a particularly desirable language.

The UB permits the optimization, but is not necessary for it. If a language had a stricter definition of pointer and memory access behavior then the optimization would still be applicable if it conformed to the assumption that people are making around the UB in C.

UB is not necessary for optimization, it just permits some optimizations which may or may not be valid and may or may not be consistent across compilers and platforms because people get to fill in the gaps with whatever they want.

Re: Modern C (2019)

#30
post #26

Earlier quoted context omitted.

UB is what allows `(&x)[1]` to happen at all. If you didn't have UB, there would be no reasonable way to allow code that messes up arbitrary pointers. A typical non-UB language wouldn't allow `(&x)[1]` and it would be easy to allow the optimization. It would be difficult or obtuse to design a non-UB language that doesn't allow optimizing y away.

Standard Forth, to my knowledge, doesn't have UB and consequently doesn't allow the optimization. That'd just be : foo CELL + 20 SWAP ! ; there. Machine languages also generally don't have this kind of UB, and don't allow the optimization. It's not impossible to imagine a C without UB, it's just not a particularly desirable language.

Parameters don't really work the same way in Forth. A similar C program would explicitly pass in an entire stack every time it runs a function, or have a global stack variable. And such a C program would disallow the optimization whether or not you consider UB.

Machine language means you have basically no rules imposed on your code at all. So it's true that you can't optimize anything, but I think that's outside the scope of normal language talk.

Post reply on HN