Live data from Hacker News

Weekend projects: getting silly with C

lcamtuf.substack.com

51–60 of 118 posts

Re: Weekend projects: getting silly with C

#52

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 knew a guy that’d auto reject C PR’s if they didn’t use the syntax if (1==x) rather than if (x==1). The former will not compile if you accidentally use variable assignment instead of equality operator (which everyone has done at some point).

That's not so much of a footgun anymore - the common C compilers will warn you about that so there's not much point in defending against it.

Same with literal format string parameters to printf functions: the compiler is very good at warning about mismatched types.

Re: Weekend projects: getting silly with C

#53
post #49

Why did I not know that this: case 1 ... 10: Is valid C? I have been programming in C for years, what standard is this from?

It appears to be a GNU C extension: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html but I couldn't find the history of the extension. I believe it is not in standard C (not sure about clang).

Re: Weekend projects: getting silly with C

#54
post #24

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…

> for example I knew a guy that’d auto reject C PR’s if they didn’t use the syntax if (1==x) rather than if (x==1). The former will not compile if you accidentally use variable assignment instead of equality operator I've seen that one and personally dislike that mindset: Making the code less readable to compensate for a disinterest in using actual static analysis tooling.

These days GCC and Clang will both give you warnings for this if you have -Wall, which everyone should.

Re: Weekend projects: getting silly with C

#55
post #15

Earlier quoted context omitted.

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 e…

The warning says to add parentheses, which sure enough silences the warning, your foot, however, still has a bullet hole in it.

> The warning says to add parentheses, which sure enough silences the warning, your foot, however, still has a bullet hole in it.

The warning also says that it's an assignment. It's a pretty clear warning meant to force the programmer to do extra work to get the error.

Re: Weekend projects: getting silly with C

#56
post #53
post #49

Why did I not know that this: case 1 ... 10: Is valid C? I have been programming in C for years, what standard is this from?

It appears to be a GNU C extension: https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html but I couldn't find the history of the extension. I believe it is not in standard C (not sure about clang).

I just tried it, and it works with clang version 17.0.6.

Re: Weekend projects: getting silly with C

#57
post #19

Earlier quoted context omitted.

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 intrin…

Sure, it's just an opinion. I think the consequences speak very well for themselves.

What consequences?

Re: Weekend projects: getting silly with C

#58
Due to the way lifetimes work in C (they begin with the block, not the declaration), the following is legal:

  #include 
  #include 

  int main()
  {
      {
          int *p = NULL;
          if (p)
          {
          what:
              printf("a = %d\n", *p);
              return 0;
          }
          int a = 123;
          p = &a;
          goto what;
      }
  }

Re: Weekend projects: getting silly with C

#59
post #47

Earlier quoted context omitted.

> Also broken compilers [1]. The issue you linked to is not a counter example because, as the poster said, g may terminate the program in which case that snippet does not have undefined behaviour even if b is zero. The fact that they bothered to mention that g may terminate the program seems like an acknowledgement that it would be valid to do that time travelling if it didn't. > Note that blog post is correct about…

The poster is me. You are right that this is not an example for time-travel. There aren't really good examples for true time travel because compilers generally do not do this. But my point is that with compilers behaving like this, people might confuse this for time-traveling UB. I have certainly met some who did and the blog posts seems to have similar examples (but I haven't looked closely now). Note that I am a me…

Ok, fair enough. I must admit I was looking at C99 as I thought that was most generally relevant, I don't follow recent C standards (as much as I do those for C++) and C23 hasn't been ratified yet. I've found your new snippet:

> In particular, all observable behavior (5.1.2.4) appears as specified in this document when it happens before an operation with undefined behavior in the execution of the program.

I consider that a change in the standard but, of course, that's allowed, especially as it's backwards compatible for well defined programs.

The wording is a little odd: it makes it sound a like you need some undefined behaviour in order to make the operations beforehand work, and, taken very literally, that operations between two undefined behaviours will work (because they're still "before an operation with undefined behavior"). But I suppose the intention is clear.

Re: Weekend projects: getting silly with C

#60
post #47

Earlier quoted context omitted.

The poster is me. You are right that this is not an example for time-travel. There aren't really good examples for true time travel because compilers generally do not do this. But my point is that with compilers behaving like this, people might confuse this for time-traveling UB. I have certainly met some who did and the blog posts seems to have similar examples (but I haven't looked closely now). Note that I am a me…

Ok, fair enough. I must admit I was looking at C99 as I thought that was most generally relevant, I don't follow recent C standards (as much as I do those for C++) and C23 hasn't been ratified yet. I've found your new snippet: > In particular, all observable behavior (5.1.2.4) appears as specified in this document when it happens before an operation with undefined behavior in the execution of the program. I consider…

The definition of UB (which hasn't changed) is: "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this document imposes no requirement."

Note that the "for which" IMHO already makes this clear that this can not travel in time. When everything could be affected these words ("for which") would be meaningless.

Post reply on HN