Live data from Hacker News

The C23 edition of Modern C

gustedt.wordpress.com

181–190 of 360 posts

Re: The C23 edition of Modern C

#182
post #95
post #77

Earlier quoted context omitted.

It was on purpose, Microsoft was done with C, the official message was to move on to C++. The change of heart was the new management, and the whole Microsoft <3 FOSS.

> It was on purpose, Microsoft was done with C Indeed, and yet here we are with C23 > The change of heart was the new management, and the whole Microsoft Yeah, agree. To me the turning point was when they created WSL.

Microsoft didn't create C23 and they don't <3 FOSS. They're accepting that they have to deal with FOSS, but installing Windows will still make your Linux system unbootable until you fix it with a rescue disk, among numerous other unfriendly things they do.

Re: The C23 edition of Modern C

#183
post #127
post #109

Earlier quoted context omitted.

int a; cin >> a; Then the program goes berserk as soon as the first non-number is read out of standard input. All the other "cin >> integer" lines are immediately skipped. Yes, I know about error checking, clearing error condition, discarding characters. But it's a whole lot of stuff you need to do after every single "cin>>" line. It makes the simplicity of cin not worth it.

How could you ever continue after the second statement without checking if you actually read an integer or not? How would you know what you can do with a?

Well in a language like Haskell you could solve this with monads and do-notation. The general idiom in Haskell is to use a Maybe or Either monad to capture success/failure and you assume you’re on the happy path. Then you put the error handling at the consumer end of the pipeline when you unwrap the Maybe or Either.

I believe Rust has adopted similar idioms. I’ve heard the overall idea referred to as Railway-oriented programming.

In C++ you could implement it with exceptions, though they bring in a bunch of their own baggage that you don’t have to deal with when using monads.

Re: The C23 edition of Modern C

#184

Earlier quoted context omitted.

The PDP-11 that C originally targeted had address modes to support the stack. Pre-increment and post-decrement therefore did not require a separate instruction; they were free. After the PDP-11 went the way of the dodo, both forms took a machine cycle so it (mostly) became a stylistic issue. (The two operators have different semantics, but the trend to avoid side-effects in expressions means that both are most often…

Please explain what you mean by "a separate instruction".

Some idiomatic C code to copy a string (I'm not saying this is good C code, but it's just an example):

    while(*d++ = *s++)
      ;
 
On the Motorola 68000 (based somewhat on the PDP-11) the code would look like:

    loop:       move.b  (a0)+,d0
                move.b  d0,(a1)+
                bne     loop
 
while on the x86 line, it would be:

    loop:       mov     al,[rsi]
                mov     [rdi],al
                inc     rsi     ; extra instruction!
                inc     rdi     ; extra instruction!
                cmp     al,0
                jne     loop
 
Yes, there are better ways to write that code for both the 68K and x86, but I hope this gets the point across.

Re: The C23 edition of Modern C

#185
Continuing to use a memory-unsafe language that has no recourse for safety and is full of footguns and is frankly irresponsible for the software profession. God help us all.

By the way, the US government did the profession no favors by including C++ as a memory-unsafe language. It is possible to write memory-safe C++, safe array dereferencing C++. But it’s not obvious how to do it. Herb Sutter is working on it with CppFront. The point stands that C++ can be memory-safe code. If you make a mistake, you might write some unsafe code in C++. But you can fix that mistake and learn to avoid it.

When you write C, you are in the bad luck shitter. You have no choice. You will write memory—unsafe code and hope you don’t fuck it up. You will hope that a refactor of your code doesn’t fuck it up.

Ah, C, so simple! You, only you, are responsible for handling memory safely. Don’t fuck it up, cadet. (Don’t leave it all to computers like a C++ developer would.)

Put C in the bin, where it belongs.

Re: The C23 edition of Modern C

#186

Personally this[1] just makes C much more complicated for me, and I choose C when I want simplicity. If I want complicated, I would just pick C++ which I typically would never want. I would just pick Go (or Elixir if I want a server). "_BitInt(N)" is also ugly, reminds me of "_Bool" which is thankfully "bool" now. [1] guard, defer, auto, constexpr, nullptr (what is wrong with NULL?), etc. On top of that "constexpr" a…

> what is wrong with NULL? For starters, you have to #include a header to use it.

Well, I always include stdio.h which includes stddef.h that defines NULL as (void *)0.

Re: The C23 edition of Modern C

#187

Most important aspect of C is its portability. From small microcontrollers to almost any computing platform. I doubt that any new version of C will see that much adoption. If I want to live on cutting edge I would rather use C++2x or Rust rather than C. Am I missing something? What benefit this supposedly modern C offers?

these features will eventually trickle down into the mainstream, kind of like C11 is doing at the moment also, unless you're targeting embedded or a very wide set of architectures, there's no reason why you couldn't start using C23 today

Or in other words, for embedded and existing code: most use c99, some use c11 and nobody uses c23 until at least 10 years from now.

Re: The C23 edition of Modern C

#188
post #45

Earlier quoted context omitted.

>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up" Where "mixing C/C++" is helpful: - I "mix C in with my C++" projects because "sqlite3.c" and ffmpeg source code is written C. C++ was designed to interoperate with C code. C++ code can seamlessly add #include "sqlite3.h" unchanged. - For my own code, I take advantage of "C++ being _mostly_ a superset of C" such as using old-style C printf…

The entire I/O streams (where std::cout comes from) feature is garbage, if this was an independent development there is no way that WG21 would have taken it, the reason it's in C++ 98 and thus still here today is that it's Bjarne's baby. The reason not to take it is that it's contradictory to the "Don't use operator overloading for unrelated operations" core idea. Bjarne will insist that "actually" these operators so…

> Don't use operator overloading for unrelated operations

This disn't stop with , they keep doing it - the latest example I can think of is std::ranges operations being "piped" with |.

Re: The C23 edition of Modern C

#189

Most important aspect of C is its portability. From small microcontrollers to almost any computing platform. I doubt that any new version of C will see that much adoption. If I want to live on cutting edge I would rather use C++2x or Rust rather than C. Am I missing something? What benefit this supposedly modern C offers?

The `thread_local` specifier is used on a few microcontroller platforms already, but would be absolutely illegal in C11 and before to use. However, it vastly simplifies memory management in a threaded context.

Why would I rather step into the world of C++ just to deal with that?

Re: The C23 edition of Modern C

#190

Earlier quoted context omitted.

Why use this operator? Like most C and C++ features the main reason tends to be showing off, you learned a thing (in this case that there are four extra operators here) and so you show off by using it even if it doesn't make the software easier to understand. This is not one of those beginner -> journeyman -> expert cycles where coincidentally the way you wrote it as a beginner is identical to how an expert writes it…

They can be useful when adding things to an array in a loop. A trivial example which removes a character from a null terminated string: void remove_char(char *s, char c) { size_t i, j; for (i = j = 0; s[i] != '\0'; i++) if (s[i] != c) s[j++] = c; s[j] = '\0'; } This might be better expressed with a higher order filter function, but C is too low level for things like that. There are also idioms for stack manipulation…

Note that in your example there appear to be three distinct meanings:

1. prefix incr/decr precedence: "stack[--sp]"

2. postfix incr/decr precedence: "s[j++]"

3. i have no particular preference for the precedence and am just using a shorthand I inherited from my ancestors whose use cases are no longer relevant to me: "i++" in your for loop

My rank speculation is that C programmers get in a habit of #3 and then forget to consider precedence in an expression where it matters.

In any case, it would be interesting to do a scan of github to see how often prefix and suffix incr/decr had to get switched up in a bugfix patch.

Post reply on HN