Live data from Hacker News

Weekend projects: getting silly with C

lcamtuf.substack.com

11–20 of 118 posts

Re: Weekend projects: getting silly with C

#11

My undergrad was entirely in the C language and I’m very glad for it. Sometimes more modern languages can throw me for a loop, no pun intended, but the beauty (and horror) of C is that you are pretty close to the metal, it’s not very abstracted at all, and it allows you a lot of freedom (which is why it’s so foot gunny). I will never love anything as much as I love C, but C development jobs lie in really weird fields…

[deleted]

Re: Weekend projects: getting silly with C

#12

My undergrad was entirely in the C language and I’m very glad for it. Sometimes more modern languages can throw me for a loop, no pun intended, but the beauty (and horror) of C is that you are pretty close to the metal, it’s not very abstracted at all, and it allows you a lot of freedom (which is why it’s so foot gunny). I will never love anything as much as I love C, but C development jobs lie in really weird fields…

In an embedded environment, overly defensive is an asset

That’s precisely where my little professional C experience was. I then switched to a python shop and was initially horrified at some conventions, took some getting used to.

Re: Weekend projects: getting silly with C

#13
This features the construct

  switch(k) {
    if (0) case 0: x = 1;
    if (0) case 1: x = 2;
    if (0) default: x = 3;
  }
which is a switch where you don't have to write break at the end of every clause.

  #define brkcase if (0) case
That might be worth using. Compilers won't love the control flow but they'll probably delete it effectively.

Re: Weekend projects: getting silly with C

#14
post #2

aren't the switch shenanigans important to the duff's device?

Duff is relying on the fact you're allowed to intermingle the switch block and the loop in K&R C's syntax, the (common at the time but now generally frowned on or even prohibited in new languages) choice to drop-through cases if you don't explicitly break, and the related fact that C lets your loop jump back inside the switch. Duff is trying to optimise MMIO, you wouldn't do anything close to this today even in C, no…

Not sure what you mean by "hacks to the type system". All modern computing essentially converged to unified memory, which is exactly C's model.

Re: Weekend projects: getting silly with C

#15

My undergrad was entirely in the C language and I’m very glad for it. Sometimes more modern languages can throw me for a loop, no pun intended, but the beauty (and horror) of C is that you are pretty close to the metal, it’s not very abstracted at all, and it allows you a lot of freedom (which is why it’s so foot gunny). I will never love anything as much as I love C, but C development jobs lie in really weird fields…

I force my students to do C development. And it turns out that it is not that hard if you approach it with modern tools which catch a lot of problems. The lack of abstraction is fixed with good libraries.

C evolved a lot and many foot guns are not a problem anymore. For example for

if (x = 1)

you nowaday get a warning. https://godbolt.org/z/79acPPro6

Implicit int, calling functions without prototypes, etc. are hard errors. And so on.

Re: Weekend projects: getting silly with C

#16
post #4

Another source of surprise: 4[arr] // same as arr[4]

Thanks to array decay to pointer, we basically have `*(array_label+offset)` which in this case of yours we have `*(offset+array_label)`; in other words, `*(arr+4)` is the same as `*(4+arr)`...that's it, really!

Re: Weekend projects: getting silly with C

#17

This features the construct switch(k) { if (0) case 0: x = 1; if (0) case 1: x = 2; if (0) default: x = 3; } which is a switch where you don't have to write break at the end of every clause. #define brkcase if (0) case That might be worth using. Compilers won't love the control flow but they'll probably delete it effectively.

Surely the following would work just as well?

  #define brkcase break;case
kinda defeats the purpose of the macro even.

Re: Weekend projects: getting silly with C

#18
post #14

Earlier quoted context omitted.

Duff is relying on the fact you're allowed to intermingle the switch block and the loop in K&R C's syntax, the (common at the time but now generally frowned on or even prohibited in new languages) choice to drop-through cases if you don't explicitly break, and the related fact that C lets your loop jump back inside the switch. Duff is trying to optimise MMIO, you wouldn't do anything close to this today even in C, no…

Not sure what you mean by "hacks to the type system". All modern computing essentially converged to unified memory, which is exactly C's model.

While it's convenient technically to have unified memory and so it makes a lot of sense for your machine code, in fact the MMIO isn't just memory, and so to make this work anyway in the C abstract machine they invented the "volatile" qualifier. (I assume you weren't involved back then?)

This should be a suite of intrinsics. It's the same mistake as "register" storage, a layer violation, the actual mechanics bleeding through into the abstract machine and making an unholy mess.

If you had intrinsics it's obvious where the platform specific behaviour lives. Can we "just" do unaligned 32-bit stores to MMIO? Can we "just" write one bit of a hardware register? It depends on your platform and so as an intrinsic it's obvious how to reflect this, whereas for a type qualifier we have no idea what the compiler did and the ISO document of course has to be vague to be inclusive of everybody.

Re: Weekend projects: getting silly with C

#19
post #14

Earlier quoted context omitted.

Not sure what you mean by "hacks to the type system". All modern computing essentially converged to unified memory, which is exactly C's model.

While it's convenient technically to have unified memory and so it makes a lot of sense for your machine code, in fact the MMIO isn't just memory, and so to make this work anyway in the C abstract machine they invented the "volatile" qualifier. (I assume you weren't involved back then?) This should be a suite of intrinsics. It's the same mistake as "register" storage, a layer violation, the actual mechanics bleeding…

I wasn't involved back then, but I know the history. I thought you were talking about something more recent.

But this is all opinions and terms such as "unholy mess" etc do not impress me. In my opinion "volatile" is just fine as is "register. Neither are layer violations nor a type system problem. That the exact semantics of a volatile access are implementation defined seem natural. How is this better with an intrinsic? What I would call a mess are the atomics intrinsics, which - despite being intrinsics - are entirely unsafe and dangerous and indeed mess (just saw a couple of new bugs in our bug tracker).

Re: Weekend projects: getting silly with C

#20

This features the construct switch(k) { if (0) case 0: x = 1; if (0) case 1: x = 2; if (0) default: x = 3; } which is a switch where you don't have to write break at the end of every clause. #define brkcase if (0) case That might be worth using. Compilers won't love the control flow but they'll probably delete it effectively.

I think it is super unclear how this works, and I would prefer the same control flow using goto, rather than the duffs device style switch abuses.
Post reply on HN