[HN Gopher] C meeting is over. C23 added:
       ___________________________________________________________________
        
       C meeting is over. C23 added:
        
       Author : ksec
       Score  : 186 points
       Date   : 2022-02-19 07:11 UTC (15 hours ago)
        
 (HTM) web link (twitter.com)
 (TXT) w3m dump (twitter.com)
        
       | rwmj wrote:
       | So true and false keywords are the only thing that has been
       | added, or am I missing a part of this thread?
       | 
       | Edit: I think one of these could be a better link:
       | https://en.cppreference.com/w/c/23 http://www.open-
       | std.org/jtc1/sc22/wg14/www/docs/n2864.pdf
        
         | NotSoVeteran wrote:
         | The linked tweet is the 4th in a sequence. If you scroll up you
         | should see 3 more tweets with more info.
        
           | [deleted]
        
           | rwmj wrote:
           | Thanks - Twitter UI is terrible.
           | 
           | I'm glad the terrible "defer" suggestion didn't make it, but
           | unfortunate that they didn't standardise the existing and
           | widely used attribute cleanup.
        
             | wartijn_ wrote:
             | This is off topic, but I don't think the problem is just
             | that the Twitter is terrible.
             | 
             | If you want to link to a thread, you should click on the
             | first tweet of that thread and copy its url. It's easy to
             | see the rest of the thread: just scroll down.
             | 
             | If you want to link to one tweet in a thread you should
             | click on that tweet and copy its url.
             | 
             | The person who posted the link to HN did the latter, while
             | they should have done the former.
             | 
             | Twitter could make it easier to see that a tweet is part of
             | a thread though.
        
               | notreallyserio wrote:
               | While we're off topic here's my little rant about Twitter
               | "threads":
               | 
               | It's easy to see all of the tweets made by the author, at
               | least those made as replies to themselves, but reading
               | the actual threads is hard or impossible. At least I
               | haven't figured out how to do it despite considerable
               | effort.
               | 
               | For example, say you want to view the replies to the
               | tweet above the linked tweet, the one about "assert".
               | There are supposedly 4 replies. If you tap that tweet you
               | remain in the same list of self-replied tweets. There are
               | replies at the end, but are they replies to the tweet you
               | want to focus on? It doesn't look like it, but who knows,
               | maybe? It's even worse on linger Twitter self-reply
               | "threads".
               | 
               | I don't know how Twitter's engineers got the well-
               | established threading pattern so wrong. This behavior
               | doesn't even increase the number of ads you see.
        
               | secondcoming wrote:
               | Twitter is bad if you don't have a twitter account. It'd
               | be great if HN could change twitter links to go through
               | nitter.net
        
           | ksec wrote:
           | I was so sure I copied the first tweet to submit. That is why
           | the title is the same as the first tweet. Somehow I messed it
           | up. May be Dang could change it to
           | 
           | https://twitter.com/__phantomderp/status/1494801365297676293
        
         | kevin_thibedeau wrote:
         | They're still macros. C will never add new keywords outside the
         | reserved namespace.
        
           | duskwuff wrote:
           | OR WILL THEY?!
           | 
           | http://www.open-
           | std.org/jtc1/sc22/wg21/docs/papers/2021/p231...
        
         | fulafel wrote:
         | The cppreference.com link says it removes "Representations for
         | signed integers other than two's complement" - this could be
         | pretty significant in making many previously implementation-
         | defined programming patterns strictly conforming, but is it
         | true? Doesn't seem mentioned in the Twitter thread.
        
           | rwmj wrote:
           | This is the accepted twos complement proposal:
           | http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf
           | 
           | It seems like a sensible simplification to me. Is there any
           | architecture that doesn't use twos complement (eg. uses
           | separate sign bit + magnitude) and could run C code?
        
             | qsort wrote:
             | Some microcontrollers used to have saturating arithmetic,
             | which is basically the only other behavior that makes any
             | sense.
        
               | MaxBarraclough wrote:
               | Perhaps I'm missing something obvious, but isn't that
               | orthogonal to representation? You could implement
               | saturating arithmetic for any representation scheme, no?
        
               | tomsmeding wrote:
               | You can only observe whether the representation is
               | 2s-complement or not if you can see what wrapping does.
        
               | MaxBarraclough wrote:
               | That doesn't sound right. You can use the union trick in
               | C (but not C++, strictly speaking) to read the bit-
               | pattern of a signed integer as an unsigned integer, for
               | example. [0]
               | 
               | Overflow of signed integer types remains undefined
               | behaviour in both C and C++. A compiler is free to make a
               | promise like _signed integer overflow is always handled
               | with wrapping_ or _signed integer overflow is always
               | handled with saturation_. (GCC has a flag, _-fwrapv_ , to
               | enable guaranteed wrapping. [1])
               | 
               | [0] https://stackoverflow.com/a/25664954/
               | 
               | [1] https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-
               | Options.html
        
             | MaxBarraclough wrote:
             | > Is there any architecture that doesn't use twos
             | complement (eg. uses separate sign bit + magnitude) and
             | could run C code?
             | 
             | I think such machines are pretty much a thing of the past.
             | This topic cropped up in a 2018 thread when C++ made the
             | same change. [0]
             | 
             | [0] https://news.ycombinator.com/item?id=17190864
        
             | Findecanor wrote:
             | The devil is not in the number representation but in the
             | details. The proposal says:
             | 
             | > Overflowing operations and out-of-range conversion are
             | generally mapped to modulo operations and cannot trap or
             | raise signals.
             | 
             | This would be a problem on x86, where INT_MIN / -1 causes a
             | #DE (divide error) exception. In C17 that is fine because
             | signed integer overflow is undefined behaviour. But if the
             | behaviour is defined, that trap would have to be caught or
             | avoided.
             | 
             | The best solution for performance would be to have a new
             | trap handler. That would have to parse the instruction to
             | find its length, and the divisor (in memory or register) to
             | differentiate it from division by zero, write the constant
             | result and remainder into the destination registers (always
             | rax and rdx thankfully) and then continue with the next
             | instruction.
             | 
             | But I think this could be difficult to do in a fool-proof
             | way, with how CPU exceptions are handled in different
             | operating systems. Some operating systems might not even
             | allow it at all.
        
               | pascal_cuoq wrote:
               | The sentence you quote is near to the words:
               | 
               | "[The C++ standardization committee] WG21 has recently
               | adapted the changes promoted in their document p12363.
               | Generally, C++ goes much beyond what is presented here:"
               | 
               | I would be extremely surprised if the proposal to make
               | signed overflow defined behavior in C made it into C23.
               | The window is narrowing and this would be a very big
               | change to the language. Making it official that 2's
               | complement is the only representation for signed integers
               | is already a large change.
               | 
               | Later in the decade, maybe.
        
       | junon wrote:
       | Having trouble figuring out if this is real. It sounds way too
       | good to be true.
        
       | Svetlitski wrote:
       | "`typeof` is standard"
       | 
       | Hallelujah, after only five decades generic, type-safe macros
       | which evaluate their arguments exactly once will _finally_ be
       | possible with standards-compliant C.
        
         | saagarjha wrote:
         | How so? You'd also need statement expressions for most of them.
        
           | throwaway3neu94 wrote:
           | No, you can use do{}while(0) usually. You only need statement
           | expressions if you want it to evaluate to a value as well.
        
       | CyberRabbi wrote:
       | Whenever I use C I use it for the express purpose of supporting
       | ancient platforms. These platforms often only support C89, so
       | that's the dialect of C to which I restrict myself. If I am able
       | to ignore those old platforms, I use C++. RAII is just so
       | convenient.
        
         | gefhfffh wrote:
         | Have you evaluated Rust instead of C++?
        
         | Koshkin wrote:
         | Indeed, RAII and function overloading are the two things I
         | sorely miss when I think of coding in C.
        
       | beeforpork wrote:
       | > Support for calling realloc() with zero size (the behavior
       | becomes undefined)
       | 
       | OMG! Please do not add _more_ undefined behaviour!
       | 
       | We really need less UB, not more! What was wrong with
       | 'implementation defined' as in C17? UB means that code that
       | exists will now break if a new compiler decides that it can be
       | smart. And we know how inventive this can get, right? Like
       | removal of 'if(new_size==0) {...}' if the compiler can prove that
       | 'new_size' went into 'realloc' before.
        
         | c-linkage wrote:
         | They'd better not convert that to undefined behavior!
         | 
         | First, the specification for malloc() says you can call it with
         | size 0 and it will still return a pointer to zero bytes; this
         | means an array of bytes having size zero is legal.
         | 
         | Second, having the compiler detect when realloc() is called
         | with size zero changes what should be a library call into an
         | intrinsic, whose very presence in the code is determined by the
         | value of its arguments[0]. If you're going to do that you might
         | as well just put exceptions in the language!
         | 
         | [0] Most compilers assume UB "can't happen" and just remove the
         | offending code altogether.
        
           | masklinn wrote:
           | > Most compilers assume UB "can't happen" and just remove the
           | offending code altogether.
           | 
           | To be clearer: UBs (specifically the assumption that they
           | don't happen) get translated into constraints (since C's type
           | system is extremely weak UBs are a very valuable source of
           | such constraints to optimising compilers), those constraints
           | are then propagated (forwards, and backwards, and upwards due
           | to inlining) and any path for which the constraint does not
           | hold can be considered dead.
        
           | enedil wrote:
           | Manual says
           | 
           | > If size is 0, then malloc() returns either NULL, or a
           | unique pointer value that can later be successfully passed to
           | free().
           | 
           | So it's not really an array of bytes of size 0.
        
             | MichaelBurge wrote:
             | What qualifies something as a "real" array of bytes?
             | 
             | All RAM is an array of bytes, so any pointer to real
             | memory(vs. virtual memory) is a pointer to an array of
             | bytes.
        
         | colanderman wrote:
         | Where did you see this? I can't find it in the Twitter thread
         | or any of the linked sources. I agree that "adding" support for
         | something by making it UB makes no sense... as that generally
         | would imply breaking forward-compatibility...
        
           | beej71 wrote:
           | Not only that, but the feature is genuinely useful.
        
       | RcouF1uZ4gsC wrote:
       | > typeof(...) is standard
       | 
       | I thought C++11 went with decltype because typeof was implemented
       | by compilers as an extension with various subtle semantic
       | differences than what they wanted.
       | 
       | I wonder why the C committee went with typeof instead of
       | decltype?
        
         | pwdisswordfish9 wrote:
         | Because that would then create subtle incompatibilities with
         | C++, stemming from the fact that C has no reference types.
         | 
         | http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2927.htm#ex...
        
         | [deleted]
        
         | bonzini wrote:
         | IIRC typeof is implemented in the same way by all compilers
         | that have it, but it had some subtle differences with what the
         | committee wanted. The differences presumably do not matter for
         | C, in fact I think it was something related to references.
        
       | vkazanov wrote:
       | It's probably better to just follow the original WG14 Document
       | log:
       | 
       | http://www.open-std.org/jtc1/sc22/wg14/www/wg14_document_log...
        
       | mojuba wrote:
       | Removing K&R style function prototypes though is kind of big. I
       | remember when one of the Objective-C upgrades started enforcing
       | K&R. I don't think ObjC will be upgraded to C23 (ever, as it's a
       | language being deprecated now I presume) so it will be stuck with
       | K&R... while the rest will move on?
       | 
       | Could someone also explain what this means for pure C in terms of
       | compatibility? If there's                 void foo();
       | 
       | would the meaning of it depend on which C standard is activated?
        
         | plorkyeran wrote:
         | Obj-C can be compiled using any version of C (and Obj-C++ can
         | be compiled using any version of C++). You already can use C2x
         | with obj-c if you desire. I don't know what "enforcing K&R"
         | means in this context, but if you think that Obj-C requires
         | using K&R-style function definitions you're very confused about
         | something.
        
         | flohofwoe wrote:
         | IME ObjC (unlike C++) automatically supports the latest C
         | standards, because ObjC just adds some syntax sugar on top of
         | C, but otherwise doesn't 'mangle' its C subset into its own
         | dialect like C++ does.
        
         | dgrunwald wrote:
         | What's being removed in C23 is the ancient K&R syntax for
         | function definitions:                   int max(a, b)
         | int a, b;         {             return a>b?a:b;         }
         | 
         | My understanding is that C23 does not change the meaning of
         | function declarations. So "void foo();" remains a declaration
         | of a function accepting an unknown number of parameters.
        
           | zh3 wrote:
           | Wow, that's annoying. There's a bunch of old code we have
           | that'll need updating (written that way to keep the line
           | lengths down).
        
             | MawKKe wrote:
             | ...can't you just configure your build system to compile
             | those modules with pre-c23 standard?
        
               | zh3 wrote:
               | Of course. But one of the great things about C is that as
               | a rule nothing breaks with compiler changes (as long as
               | appropriate care has been taken) which this appears to
               | violate.
        
             | klyrs wrote:
             | All the compilers I use have a default C version, and an
             | optional flag to control which version to use. It's a non-
             | issue.
        
             | rightbyte wrote:
             | Maybe the compiler will add a extension flag? I mean the
             | K&R declarations still need to be supported in the compiler
             | for earlier standards.
        
           | mojuba wrote:
           | According to the OP tweet though, `foo()` is now a function
           | that takes no arguments.
        
             | leetrout wrote:
             | Agree the tweet makes it seem the behavior is changing.
             | 
             | Edit: parent is correct it IS changing
             | 
             | > We could make this change because foo() decls and
             | definitions had been deprecated since C89/99, longer than
             | I've been alive.
             | 
             | > Implementations will likely warn on foo() decls for a
             | while, and error if someone calls it with foo(too, many,
             | args);.
             | 
             | https://mobile.twitter.com/__phantomderp/status/14948125950
             | 6...
        
             | jesprenj wrote:
             | Wouldn't int foo(void) be a function that takes no
             | arguments and int foo() a function that takes an _unknown_
             | number of arguments?
        
               | suprjami wrote:
               | Yes, that's the problem.
        
             | suprjami wrote:
             | That's a different thing. That's implied `foo(void)`.
        
               | messe wrote:
               | It WAS a different thing. That's changing in C23.
        
             | zx2c4 wrote:
             | Here's the document for that change: http://www.open-
             | std.org/jtc1/sc22/wg14/www/docs/n2841.htm
             | 
             | > In this proposal, a function declarator without a
             | parameter list declares a prototype for a function that
             | takes no parameters (like it does in C++).
             | 
             | And it seems like gcc implements this under -std=c2x now:
             | zx2c4@thinkpad /tmp $ cat a.c         int blah()         {
             | return 7;         }                  int main(int argc,
             | char *argv[])         {                 return blah(argc);
             | }         zx2c4@thinkpad /tmp $ gcc -std=c17 a.c
             | zx2c4@thinkpad /tmp $ gcc -std=c2x a.c         a.c: In
             | function 'main':         a.c:8:16: error: too many
             | arguments to function 'blah'             8 |         return
             | blah(argc);               |                ^~~~
             | a.c:1:5: note: declared here             1 | int blah()
             | |     ^~~~
        
             | duskwuff wrote:
             | Which is much more consistent, IMO.
             | 
             | int foo(int, int) is a function taking two arguments. int
             | foo(int) is a function taking one argument. int foo() ought
             | to mean a function taking no arguments, not a function with
             | an unspecified number of arguments!
        
       | pkrumins wrote:
       | C is the only sane language left. It never changes and it lets us
       | write code that just works. We can focus on getting things done
       | and shipping rather than learning new features and Googling
       | compiler errors. Learn once, ship forever.
        
         | wffurr wrote:
         | ...except it just changed.
         | 
         | And you will be forever left writing insecure memory unsafe
         | code.
        
           | pkrumins wrote:
           | One change per decade is not a change.
        
             | zeckalpha wrote:
             | More than once per decade: C11, C17, C23
        
               | blinzy wrote:
               | I guess you can say C17 is a change if you want to be
               | pedantic except it didn't actually introduce any new
               | features; it just corrected some defects found in C11.
               | 
               | So we have C89, C99, C11, and C2X (C23?) as the only
               | revisions introducing new stuff...
        
         | phendrenad2 wrote:
         | C99 is the last sane language left. The additions since then
         | are just minor syntactic sugar.
        
         | sys_64738 wrote:
         | It's also upwardly compatible so no messing with code from a
         | deprecated version. Python 2 to python three has this issue. If
         | I need to change my code to make it run on the latest language
         | standard then that is a big red flag for me.
        
         | drran wrote:
         | Majority of CVE's are because of C memory model, which is fixed
         | in modern languages. C memory model is the constant source of
         | vulnerabilities, thus it better to write new code in a memory
         | safe language, like Rust.
        
           | pkrumins wrote:
           | Rust is a syntax error, not a programming language.
        
           | moralestapia wrote:
           | >Majority of CVE's are because of C memory model
           | 
           | I haven't checked that but I believe you. My only nitpick is
           | that I wouldn't put the whole blame for that on C, as there
           | are proper ways to produce "safer"[1] code. What other
           | languages did was lower the entry barrier to write better
           | code, but that doesn't mean one language is inherently better
           | that another.
           | 
           | 1: No code is ever safe, not even formally verified code.
        
           | phendrenad2 wrote:
           | C and Rust have the same memory model though, unless you're
           | using a definition of "memory model" that I'm unaware of.
        
           | masklinn wrote:
           | > Majority of CVE's are because of C memory model
           | 
           | "Memory safety" (or lack thereof) is probably less ambiguous:
           | usually "memory model" is the interaction between program and
           | memory, specifically as it pertains to concurrency. And in
           | the latter understanding I believe C has about the same model
           | as C++, which is also the one adopted by Rust. And while it's
           | fiddly, it's not a complete disaster.
        
         | rightbyte wrote:
         | Ye the churn is crazy in many languages. I almost had a heart
         | attack when the twitter post stated that "true" and "false" are
         | keywords in C23. However that seems incorrect.
         | 
         | On my last workplace we argued if we dared to use stdint.h,
         | since it was so new and fancy. I was a proponent, but there is
         | something calm over discussing whether to use 23 year old
         | additions or not.
        
       | sys_64738 wrote:
       | Does anybody bother about the stuff after C99?
        
         | rossy wrote:
         | MSVC just got C11 support a little over a year ago, so you
         | won't see many big cross-platform projects using it yet,
         | unfortunately. Some projects can optionally use C11 stdatomic.h
         | and stdalign.h to replace old OS and compiler-specific
         | extensions, but most of them still keep fallback code in case
         | C11 isn't available.
        
           | mprovost wrote:
           | So does that mean we should expect C23 support in ~2033?
        
         | pkrumins wrote:
         | Nope.
        
       | mungoman2 wrote:
       | I can't tell if this is serious.
       | 
       | Surely if you're still using C now it's for legacy reasons. And
       | if using it for legacy reasons you are likely stuck using an old
       | C standard.
       | 
       | So who will use C23?
        
         | rwmj wrote:
         | Many things on a Linux system is written in C, and despite the
         | noise on HN, developers who gets stuff done are constantly
         | writing new code in C all the time.
        
           | pjmlp wrote:
           | Including plenty of new CVEs, we have to keep the security
           | industry job market safe.
        
             | rwmj wrote:
             | Sure, I'm certainly not arguing that C is a good language.
             | In RHEL we turn all warnings on, compile everything with
             | hardening flags, use valgrind during development, and feed
             | everything through Coverity.
        
               | pjmlp wrote:
               | The exception that confirms the rule.
        
               | rossy wrote:
               | The exception? It's standard practice for distros to
               | compile with hardening flags, and if RH submits the bugs
               | they find with Coverity upstream, that protects the 1000s
               | of C projects they package.
        
               | pjmlp wrote:
               | Standard practice they say,
               | 
               | https://googleprojectzero.blogspot.com/2021/12/this-
               | shouldnt...
        
               | torstenvl wrote:
               | Mozilla is not a Linux distro.
               | 
               | You have made dozens of negative (and sometimes rude)
               | comments in this thread. I'm curious why you're spending
               | so much time and energy being negative. If C isn't
               | something you're interested in, why not just ignore it
               | and move on?
        
               | axiosgunnar wrote:
               | > In RHEL we turn all warnings on, compile everything
               | with hardening flags, use valgrind during development,
               | and feed everything through Coverity.
               | 
               | Surely the compile time is not 100ms anymore then?
        
           | diegocg wrote:
           | > developers who gets stuff done are constantly writing new
           | code in C all the time.
           | 
           | The amount of new C projects being created is falling at a
           | fast rate. C isn't going anywhere, but it's certainly losing
           | rapidly its prominence in the systems programming area.
        
             | rwmj wrote:
             | [citation needed]
        
               | pjmlp wrote:
               | You can start by C compilers nowadays written in C++,
               | Arduino, AUTOSAR security standard, CUDA, DirectX, Metal,
               | GoDot, Vulkan helper libs, SYSCL, ...
        
               | phendrenad2 wrote:
               | Those are just headlines, is there any evidence that
               | those are actually overtaking C, and that the C++ used
               | isn't just "C style C++"?
        
         | [deleted]
        
         | phendrenad2 wrote:
         | I'll keep writing things in C, because it maximizes my
         | productivity and gives me extra time to make it secure (less
         | time than it would require to write it in Rust in the first
         | place).
        
         | dkjaudyeqooe wrote:
         | C is a portable alternative to assembly language.
        
           | pjmlp wrote:
           | When the world is a PDP-11.
        
             | nec4b wrote:
             | And x86, Arm, PIC, Xtensa,... and everything else.
        
               | pjmlp wrote:
               | There is where you went off rails, with greetings from
               | ACM.
               | 
               | https://queue.acm.org/detail.cfm?id=3212479
        
               | nec4b wrote:
               | I'm so glad that you have linked this article from
               | Chisnall. I can now ask you in what ways is the abstract
               | model of a machine on which assembly language operates
               | on, different from the one on which the C language
               | operates on?
               | 
               | This is the claim which started this thread:
               | 
               | >>C is a portable alternative to assembly language.
        
               | pjmlp wrote:
               | C's abstract machine is leaky and full of surprises when
               | UB comes into play for one.
               | 
               | Second when people talk about C being portable Assembly,
               | they mistakenly assume to know what comes out of the
               | compiler's backend.
               | 
               | Third, unless we are speaking about PDP-11 like CPUs,
               | modern CPUs have tons of capabilities not exposed to ISO
               | C.
               | 
               | Finally, since 1958 there are portable alternatives to
               | Assembly in systems programming with JOVIAL being one of
               | the first remarkable ones, yet another thing that C did
               | not invent.
        
               | nec4b wrote:
               | You haven't answered the question?
               | 
               | Maybe because is there is no concernable difference
               | between abstract machine models of both languages? You
               | can't do anything more about instruction reordering or
               | cache invalidation at the CPU level with assembly than
               | you can with C.
        
               | pjmlp wrote:
               | You surely can, better read those CPU manuals about line
               | bus controllers.
        
               | nec4b wrote:
               | Have you? I used to write device drivers mostly on ARM
               | architectures and I have newer seen an instruction which
               | would let me precisely control CPU instruction ordering
               | or what it does with cache that I couldn't do in C.
        
               | pjmlp wrote:
               | That is why stuff like V-Tune exist with micro-ops
               | profiler and pipeline debugging, maybe ARM should provide
               | better tooling.
        
               | nec4b wrote:
               | This tool helps as much with C (or even higher level
               | languages) as it does with Assembly. It doesn't change
               | the fact both languages work on the same abstract machine
               | model.
        
               | pjmlp wrote:
               | What is C's abstract model for NEON?
        
               | nec4b wrote:
               | A simple c library:
               | 
               | https://github.com/projectNe10/Ne10
               | 
               | You have not yet shown an argument for why c is not a
               | portable assembly.
        
           | kaba0 wrote:
           | I don't see my SIMD instructions anywhere.
        
             | jdkjs wrote:
             | Here:
             | https://www.intel.com/content/www/us/en/docs/intrinsics-
             | guid...
        
               | pjmlp wrote:
               | That isn't C, rather Intel C.
        
             | nec4b wrote:
             | The word "portable" means a subset of everything possible.
             | Do you think every CPU architecture supports SIMD?
        
               | foxfluff wrote:
               | > The word "portable" means a subset of everything
               | possible.
               | 
               | Exactly; for example, C has single precision and double
               | double precision floating point, 64 bit types, and
               | complex arithmetic because every CPU architecture has
               | those built-in.
        
               | nec4b wrote:
               | No, but those things can be easily emulated on every
               | hardware or simply not used. One more reason to use C
               | instead of plain assembly.
        
           | pornel wrote:
           | Where's my overflow flag?
        
             | nec4b wrote:
             | Not all CPU's have overflow flags. On those that have them,
             | you can also usually access them in C in a non portable
             | way.
        
             | uecker wrote:
             | C23 will get support for checked integer operations that
             | report overflow.
        
         | brian_cloutier wrote:
         | At a previous employer of mine we would have happily switched
         | to c23. Postgres is written in c and if you want to write an
         | extension for Postgres you're going to have the easiest time if
         | your extension is also written in c. However, there's no reason
         | not to use the newest c version.
         | 
         | So, c is not just for legacy code.
        
         | DyslexicAtheist wrote:
         | _> So who will use C23_
         | 
         | I can't say if I'd immediately jump to C23 but I'll be thrilled
         | to give it a try.
         | 
         | Currently I'm rewriting an entire automotive OCPP charging
         | point and it's associated CSMS in C because the original dev
         | (who has no experience with Edge/IoT and just Cloud/SaaS)
         | thought it was a great idea to implement this in golang. The
         | binary size alone is already a problem where all I have is 30MB
         | (needs to be shared with logs, sqlite, and 2 another "user-
         | space" application).
         | 
         | I could have chosen Rust/Zig/Nim (I really wanted to) but the
         | client rejected it for very good reasons that have nothing to
         | do with type-safety/performance/security but are all about
         | good-business practice and risk management:
         | 
         | - when I leave in a few weeks, there are plenty engineers
         | inside the company who can maintain the system.
         | 
         | - the domain is quite niche so to understand their solutions
         | and requirements you can't do away without an occasional trip
         | to their office. the client is not in a capital city with a
         | vibrant tech-scene and weekly meet-ups and lacks the talent-
         | pool.
         | 
         | The constraints by the market (scarcity) makes Rust/Nim/Zig (my
         | personal front-runners) very risky tools.
         | 
         | C++ could have been an option but it's total overkill because
         | most of the components you need to build this (websocket, mqtt,
         | http, sqlite, zlib, openssl, ...) are anyway implemented in C
         | and I actually don't want things like exceptions or templates
         | in this _at all_ for performance reasons.
         | 
         | If you split your OS into layers from HW (ring-0) all the way
         | to layer-5 (process management e.g. systemd etc) then 99% is
         | still written in C. So your argument throws every layer under
         | the bus except user-land (L-6).
         | 
         | C isn't going away only because of embedded/IoT. It's going to
         | stay because choosing a language is like the "3 most important
         | rules in real-estate: location. location. location".
         | 
         | The language is your location and your primary lock-in factor
         | for your solution/business. Once you've decided on language the
         | only way to change this is an entire re-write. Even if you
         | rewrite you still have to consider culture and available
         | resources that must be in place long before you chose the
         | programming language. And keep in mind the people who all took
         | stakes in the original implementation and must all be sold on
         | the idea that whatever new replaces the old "is sooo much
         | better". That's not an engineering problem but a power/people
         | problem.
         | 
         | Edit: So just because "the engineer inside of me" wants to use
         | Rust/Nim/Zig or whatever new to satisfy my intellectual
         | curiosity is not enough reason. In fact my potential inability
         | to see beyond that is a good reason for them to be very very
         | careful about what advise I give.
        
           | WithinReason wrote:
           | Is it a good summary that the only reason for deciding for C
           | instead of Rust/Nim/Zig is that not enough programmers know
           | Rust/Nim/Zig?
        
             | DyslexicAtheist wrote:
             | imo not the only reason but it's the most cited one by
             | those who give me a budget and limit my freedom to use the
             | tool I personally think is right for the job. just because
             | I can sell an engineering audience on my (IMHO correct but
             | artisanal) views doesn't mean it's what is best for the
             | business.
             | 
             | Because they know the moment they come back "crying" saying
             | "we can't find anyone with these skills" I'll consider it
             | as their problem, because I for sure am not going to help
             | sifting through LinkedIn profiles or get involved with
             | their "talent acquisition strategy" (at least not in the
             | capacity of an architect/engineer)
             | 
             | I'm not saying always use C but if you have a very narrow
             | skill-set in your team then switching languages is a long-
             | term strategic decision that goes well beyond the opinion
             | of the SW-teams. It's about strategy, budget, risk. That's
             | probably true for most new languages / tools that replace
             | the status-quo and not just about C vs Rust&Co. If I bring
             | in a new technology then I'd first use them in parts of the
             | system that aren't core-business (e.g. my infra automation
             | etc) and then gain experience slowly with them before
             | considering allowing them into parts that make up my core-
             | business. It's a long term project to adapt a new
             | technology not something a few devs decide. (start-ups
             | switching from MVP to real products might be an exception,
             | as are bigger companies switching from PoC to a real
             | implementation, etc.)
        
               | WithinReason wrote:
               | Well then "legacy reasons" cited by GGGP was actually
               | right. That's what I was wondering as well.
        
             | blinzy wrote:
             | From my personal experience, at work we use C and not Rust
             | because for really low-level code (e.g., kernel bypass,
             | niche datastructures, real-time, etc.) I believe Rust would
             | have to use "unsafe" due to work with raw pointers and
             | other code that can't be easily, or at all, expressed
             | otherwise. In such a scenario a lot of the advantages Rust
             | supposedly brings are diminished or gone.
             | 
             | When that happens, considering that our company's
             | knowledge/experience with C (or C++, although not my case)
             | is vastly deeper than with Rust it makes no sense to choose
             | it for any of that type of code we write, old or new.
             | 
             | Zig looks promising but it's still too soon to take any
             | risk in adopting it; in 5 years time it may be worth
             | revisiting it and see how it has matured...
             | 
             | Finally, software we may write but that gives us no
             | competitive advantage over other businesses, sure that can
             | be in Rust, Go, Java, Python, whatever.
        
         | foxfluff wrote:
         | I will continue to use C because I haven't seen an appealing
         | alternative.
        
         | 10x-dev wrote:
         | C is the best choice if you want _all_ of: small (both language
         | and binaries), fast (both compiler and binaries), obvious (no
         | /minimal complex magic), close to the metal, with excellent
         | debugging support, portability and integrations.
         | 
         | No other language has been battle tested for longer and more
         | extensively than C.
         | 
         | Your kernels, OSes, drivers, databases, web servers and
         | compilers are written in C.
         | 
         | If some of these features are not important to you, there are
         | hundreds of slower, more complex and less portable languages to
         | choose from, that provide other benefits instead, such as more
         | convenience, more correctness and higher level abstractions.
        
           | kaba0 wrote:
           | C isn't _that_ small, compare it to a Zig hello world. Fast
           | is relative -- due to C not having good expressive
           | /abstracting powers, it will leave you to inferior solutions,
           | eg. counting string length multiple times at call sites, vs
           | C++'s small string optimization, which is simply not possible
           | in a user-ergonomic way in C. Regarding obviousness, I would
           | add UB here, so Zig for example would beat it.
           | 
           | C is not any closer to the metal than other system level
           | programming languages, this myth should just die. Your code
           | at -O3 gets mangled to oblivion, unless you are a compiler
           | writer of the respective compiler, you will have no idea on
           | the generated code. This is the exact same as with C++, Rust,
           | etc, hell, C doesn't have proper simd support, so in a way
           | the former two is closer to the metal.
           | 
           | But I do agree on portability and integrations - so C will
           | not die, but I really have a hard time seeing why should I
           | choose C over any of the listed languages, unless I target
           | some obscure CPU architecture.
        
             | moralestapia wrote:
             | >due to C not having good expressive/abstracting powers
             | 
             | I disagree, if anything, C's scantness forces you to
             | abstract things much properly, unless you plan to write
             | pages of boilerplate code here and there.
        
               | kaba0 wrote:
               | With all due respect - how do you write a string library
               | in C then? Char* is not one.
        
             | dzaima wrote:
             | In C it's possible (and, to some level, very much
             | encouraged) to write your own things to replace whatever
             | built in thing you don't like for whatever reason, be it
             | speed, size, portability.
             | 
             | C not having fancy built-in structures means programmers
             | are more careful about choosing simple ones, which
             | dramatically cuts down the amount of completely pointless
             | generated code. -O3 can optimize registers and maybe memory
             | reads/writes, but it can't remove reallocation from each
             | call to a vector push, remove a reference count from a
             | whole object type, or do pretty much anything with any
             | moderately complex heap data structure. Sure, that comes at
             | the cost of more advanced things being horrible to write,
             | but it's a trade-off.
             | 
             | And I'll just disagree that UB must be unobvious. To me,
             | it's one of the most useful optimization tools. You can
             | check for it with sanitizers, and explicitly invoke it to
             | convey information about hidden behavior to a compiler.
             | It's not magic.
        
               | kaba0 wrote:
               | > C not having fancy built-in structures means
               | programmers are more careful about choosing simple ones
               | 
               | Resulting in linked lists everywhere which have pretty
               | terrible performance characteristics. You should be
               | worried about those way before the occasional vector push
               | reallocation cause you any problem. (And you can specify
               | initial capacity so there is that)
        
               | dzaima wrote:
               | linked lists - true, but at least when you write them
               | you'll be certain of what they do, and, coupled with
               | knowledge of cache performance, precisely how bad they
               | are. About reallocation I don't even mean the copying,
               | but just the code needing to check for the chance
               | overflow on every push. Besides the obvious waste of
               | instructions to check for that, it also clobbers
               | registers even if the branch isn't taken, and thus will
               | easily result in a lot more unnecessary spilling to the
               | stack. This kind of pointless thing happens in a ton of
               | data structures.
        
               | kaba0 wrote:
               | Branch prediction exists so the common case can be made
               | very fast (much faster than jump to this remote pointer),
               | and also, rust uses an optimizing compiler for a reason.
               | Eg., you use a vector inside a for, the vector's code can
               | be inlined and the checking part be done only at the
               | boundary. Also, one can also manually perform an
               | unchecked push/get/whatever as well.
        
               | dzaima wrote:
               | The common case may be fast, but it's still slower than
               | not having a rare case in the first place. The untaken
               | branch will still affect register allocation (out of the
               | ~15 x86-64 general-purpose registers, only 5 (6 if you
               | count rbp) preserve data after a non-inlined function
               | call in the System-V ABI (of which there will be at least
               | one, ending in malloc somewhere), and the compiler has to
               | accommodate both taken and untaken at the branch end) and
               | will eliminate any hope of SIMD vectorization, among
               | other wrecked optimizations.
               | 
               | Unchecked operations are acceptable if your code has a
               | single hot loop, but if you have a hundred small
               | functions, each taking 1% of the time, you probably won't
               | carefully examine every stdlib function each of them uses
               | and write code to "work around" every unnecessary thing
               | the stdlib does.
               | 
               | Yes, that's a ton of micro-optimization, but micro-
               | optimization can bring a ton of speedup, so I'll take
               | whatever makes it simpler (or not needed in the case
               | where you already know what will happen due to having
               | written it)
        
               | kaba0 wrote:
               | Feel free to wrap it into a repr(transparent) type which
               | exposes the unsafe operations by default.
               | 
               | But I seriously doubt that programs would benefit much
               | from these micro-optimizations - there are rare and
               | unfortunate cases where indeed there is no one single
               | bottleneck for a program and thus there is no simple way
               | to improve performance, but the vast majority of programs
               | spend all their life in a tight hot loop, and anything
               | else doesn't matter in the slightest - hell, as mentioned
               | C gets away with as many linked data structure as they
               | want, but writing those in goddamn bash would suffice as
               | well.
        
             | 10x-dev wrote:
             | Are you going to mix all those languages into one project
             | and somehow use their advantages but steer away from their
             | disadvantages?
             | 
             | Sure, other languages have caught up or have improved on
             | some of the features where C shines.
             | 
             | Let's remove portability and integration from the feature
             | list, because that's strongly related to C's tenure.
             | 
             | Which _one_ of the languages you listed matches the rest of
             | the feature set I brought up?                 * Small
             | language       * Fast compile times       * Fast binaries
             | * Small binaries       * Great debugging experience       *
             | Close to the metal
             | 
             | In my opinion, they all fail in at least one category, and
             | that's expected - additional functionality can't come for
             | free. You can only accept its cost.
        
               | xigoi wrote:
               | Zig? I personally haven't used it, but based on what I've
               | heard about it, it fulfills these criteria.
        
               | chaz72 wrote:
               | That's what I am betting on - but it isn't 1.0 yet, and
               | that matters too.
        
               | foxfluff wrote:
               | And they fail in other categories too, e.g. C can be very
               | terse whereas most modern so-called replacements tend
               | towards verbose. For me that's a development exactly in
               | the wrong direction; I'd rather have a more terse C.
        
           | mprovost wrote:
           | C certainly has been battle tested but I wouldn't say that it
           | passed with flying colours. Every one of the examples that
           | you cite has had bugs/crashes/vulnerabilities that would have
           | been avoided with newer languages.
        
           | WithinReason wrote:
           | Languages exist that compile to C which gives them many of
           | the above advantages and more, so why choose C over them?
        
             | 10x-dev wrote:
             | Control over the code that actually runs.
             | 
             | We already lose quite a bit of control with C (e.g. it
             | reorders your code as it pleases) to gain portability
             | across CPUs, otherwise we'd have to rewrite the code in
             | several assembly languages.
             | 
             | If you consciously choose to give up even more control over
             | the code that runs (because a compiler that targets C
             | necessarily adds another layer of autogenerated code that
             | you don't control) then it better be a wise tradeoff.
        
               | WithinReason wrote:
               | The downside of reordering being performance? Or
               | something else?
        
               | 10x-dev wrote:
               | Performance is usually the upside. The downside is subtle
               | bugs that can happen due to side effects of the
               | statements being reordered between sequence points.
        
               | WithinReason wrote:
               | AFAIK compilers don't reorder if it would change the
               | result.
        
               | Thiez wrote:
               | Compilers not allowed to violate the language spec when
               | optimizing. But the spec may be fairly generous in its
               | allowed interpretations, which may not match what a
               | programmer may naively expect. C, with its _many_
               | undefined behaviors and implementation defined behaviors,
               | is especially dangerous.
        
             | dig1 wrote:
             | Depending on transpiler (compilers that will compile to C),
             | you can get near representation in C (rarely) or something
             | completely different (frequently). In Scheme/LISP world
             | (where transpilers were popular for a while), even a simple
             | expression like "(+ 1 1)" will rarely give you something
             | like: "int a = 1 + 1;". I've seen these things would
             | produce dozen of lines of various boxing/unboxing calls,
             | type checks and GC protection marks. If the compiler is
             | really aggressive, it will just put "2" as a constant.
             | 
             | I think that the only benefit of "compiling to C" was
             | reusing existing compilers, not tooling around it. Also,
             | debugging that code is a nightmare unless you are intimate
             | with transpiler internals.
        
               | sys_64738 wrote:
               | A compiler that translates to another language used to be
               | called a translator.
        
               | zabzonk wrote:
               | All compilers covert programs in one language (say C)
               | into another, (say assembler or machine code), and they
               | are called compilers. The whole transpiler thing is a bit
               | bogus, but a C compiler has never IME been called a
               | translator.
        
             | raptorfactor wrote:
             | Having never used such a language, I'm curious, what's the
             | debugging experience like? Can I source level step the
             | application in the original language or do I have to debug
             | the generated C?
        
               | TingPing wrote:
               | It is always a pain to debug transpiled C IME.
        
               | rightbyte wrote:
               | You can put in line pragmas for e.g. gcc that will point
               | you from "foo.gen.c" to "foo.fancylang". However it is
               | not very useful unless the fancy language matches C's
               | structs and native types and also does not mangle names.
        
             | rwmj wrote:
             | One of the criteria is "excellent debugging support" which
             | you don't get with transpiled languages, since you'll be
             | buried in generated code when you open the debugger.
        
               | pjmlp wrote:
               | Languages like Eiffel prove this isn't the case, it is a
               | matter of proper debug tooling.
        
               | zabzonk wrote:
               | Of course, Eiffel is such a popular and widely used
               | language, with a great toolset. /s
        
               | pjmlp wrote:
               | The amount of users doesn't change the fact of the
               | tooling quality, but no wonder, UNIX folks tend to only
               | take free beer, so what do they know about fine wine.
        
               | zabzonk wrote:
               | I've read the Eiffel books, and tried to use the Eifell
               | tools, on Windows - a horrid experience. I am not a "UNIX
               | folk" and I can't imagine what comparing UNIX and Eifell
               | has to do with anything. It is basically an unuseable
               | programming language and toolset, promoted by an
               | egomaniac with a grudge against C++.
               | 
               | If you disagree, please provide a link to something
               | medium sized and useful written in Eifel.
        
               | pjmlp wrote:
               | Useful to whom?
               | 
               | To you or the companies that keep Eiffel Software in
               | business for 30 years?
        
               | zabzonk wrote:
               | > the companies that keep Eiffel Software in business for
               | 30 years?
               | 
               | Such as? If you can't provide links to people using
               | Eiffel succefuly, then maybe there are none.
        
               | xigoi wrote:
        
         | shakna wrote:
         | How many of your preferred programming languages are written in
         | C?
         | 
         | Yes, many self-host, but a considerable number of them don't
         | want the complications that can bring.
        
           | pjmlp wrote:
           | Modern C compilers are written in C++.
           | 
           | So much for C's simplicity in writing compilers.
        
             | shakna wrote:
             | Yes, C can be simple for writing a compiler. [0][1]
             | 
             | No, optimisation, on the other hand, is not a simple
             | problem.
             | 
             | [0] https://github.com/rui314/8cc
             | 
             | [1] https://github.com/rui314/chibicc
        
               | pjmlp wrote:
               | Naturally it can be simple, it was already a basic
               | language when compared with what 1960's have produced.
               | 
               | The evolution of Bootstrapping CPL compiler + a set of
               | basic types.
        
             | uecker wrote:
             | There are plenty of C compilers written in C. Large
             | compiler suites for C/C++ are usually written in C++. But
             | as a contributor to GCC, I can say that large parts of the
             | code still look very much like C.
        
               | pjmlp wrote:
               | Plenty of compilers... right.
               | 
               | If you cannot compile GCC with a C compiler, it isn't C.
        
               | uecker wrote:
               | There a couple of open source C compilers TCC, SDCC,
               | tendra, chibicc, ACK, LCC, PCC, etc. and also many
               | commercial ones.
               | 
               | It is true that GCC is not written in C anymore, but it
               | is easy to see that the code is still relatively close. I
               | am also myself writing a C compiler in C at the moment
               | and there is no problem at all.
        
         | jonp888 wrote:
         | There are many many people out there using C for embedded
         | software.
        
           | mkl95 wrote:
           | There are tons of CPython users AKA Python's default
           | implementation... the software world is full of high level
           | abstractions built on top of C.
        
           | sam_bristow wrote:
           | The problem is that embedded compilers are not known for
           | keeping up with the standards. The only hope is that the
           | moves to GCC and Clang continue.
        
             | bsder wrote:
             | gcc (thankfully) is the default (you download gcc compiled
             | for ARM directly from ARM itself) for ARM embedded so when
             | gcc gets it, ARM gets it.
             | 
             | So, presumably, RISC-V will also get it at the same time.
        
             | pkrumins wrote:
             | No one cares about the standards. We only care about
             | getting things done by writing regular C code that works.
        
               | uncomputation wrote:
               | Huh? What do you think defines "regular C code that
               | works"? Standards.
               | 
               | Every compiler you have used operates at a bare minimum
               | on the C standard. That's why they are often advertised
               | (if not GCC/Clang which are assumed to be up to date) as
               | "C(89|99|11|17) compliant." "Code that works" is code
               | which is operates under constraints and guarantees
               | specified by a standard, anything else is undefined or
               | unportable.
        
               | xigoi wrote:
               | I'll rather have code that runs on an actual computer
               | than code that should hypothetically run according to a
               | long document that costs 60 dollars to read.
        
               | pkrumins wrote:
               | Only the standards people care about standards. We
               | (programmers) want to just get things done. We don't care
               | about the standards. No one reads the standards. Also no
               | one cares about portability. All computers have been the
               | same for the last 20 years.
        
               | pjmlp wrote:
               | Right, then comes the day another OS or CPU needs to be
               | supported and some clever developers learn their lesson
               | about language standards during a couple of late nights
               | tracking down production issues.
        
               | drran wrote:
               | We, developers, care about standards, because we want to
               | get things done once.
        
               | flyinglizard wrote:
               | Embedded environments are specific and esoteric enough
               | that compiler portability is the least of your concern
               | when migrating code from one platform to the other.
        
         | kstenerud wrote:
         | I will.
         | 
         | C is everywhere and is not going away (it's #2 on TIOBE and on
         | the rise again). Now that fewer people are learning it, I get
         | more juicy contracts.
        
           | reassembled wrote:
           | I feel like there's actually a growing subculture of C
           | programmers of late, seemingly spawned by Casey Muratori's
           | Handmade Hero series, Zed Shaw's "Learn C The Hard" way and
           | other more recent popularizations of C and low level
           | programming ideas. There's a whole "Handmade" software scene
           | growing up, seemingly as a reaction against the bloat and
           | over engineering of more recent software trends like Electron
           | and web apps. Just the other day I stumbled across a vibrant
           | Discord group focused on a fairly new but surprisingly
           | feature complete game engine called Gunslinger, written
           | entirely in C99. I've been working on my own C-based game
           | engine for awhile too after having been exposed to the ideas
           | of Handmade Hero, as well as from the influence of a good
           | friend who has been writing games in C for many years. He's
           | now working on an application called Pixel CNC for generating
           | 3D tool paths from 2D images.
        
             | saagarjha wrote:
             | > seemingly spawned by Casey Muratori's Handmade Hero
             | series, Zed Shaw's "Learn C The Hard" way
             | 
             | It's kind of unfortunately, really, because both authors
             | have very skewed viewpoints of C that are arguably quite
             | incorrect.
        
               | edflsafoiewq wrote:
               | What viewpoints are those, for those of us unfamiliar?
        
               | saagarjha wrote:
               | Zed Shaw doesn't really like C because it lets you shoot
               | yourself in the foot. This is an OK opinion to have, but
               | then he goes and writes books about C that basically talk
               | about how the language is bad (ok, I guess?) but the then
               | claims he has solutions to these problems, without
               | understanding that the problems he has with C are not
               | solvable within the language (for example, when handed an
               | arbitrary pointer, there is _no way_ to tell whether it
               | is valid).
               | 
               | Casey Muratori is fundamentally at odds with how
               | undefined behavior works in C and has opinions(tm) on how
               | to fix the language to make things work the way he wants
               | them to, when in reality he just probably wants another
               | language.
        
               | throwaway2214 wrote:
               | also arguably quite correct
        
               | Didah wrote:
               | Out of curiosity: why do you consider Casey's viewpoint
               | incorrect?
        
               | saagarjha wrote:
               | Casey doesn't really understand how optimizing compilers
               | work, so he likes to talk about how they keep breaking
               | his code and that they should just run the optimizations
               | that won't do that.
        
             | plafl wrote:
             | C++ requires to devote your life to it but you can learn C
             | and spend a year using it and suddenly you have a dangerous
             | but powerful tool in your toolbox forever.
        
               | gefhfffh wrote:
               | It's not like C++ is always the only alternative, see
               | e.g. Rust which is way simpler
        
               | lumb63 wrote:
               | I agree that Rust is simpler than C++ (in some ways), but
               | I'd say it is far more complex than C.
        
               | Thiez wrote:
               | That depends on how you define complexity. It is far
               | easier to write a working program without memory leaks,
               | various types of vulnerabilities, and undefined behavior
               | in Rust than it is in C.
        
               | phendrenad2 wrote:
               | It depends on what level of security you need. If you're
               | writing a 3D game engine, a minor memory leak probably
               | isn't worth the extra time required to write it in Rust.
               | Even if you're writing a kernel, fuzzing and formal
               | verification can get you 99.999 of the way to the
               | guarantees of Rust.
        
           | pornel wrote:
           | C is probably still popular, but TIOBE is less accurate than
           | a horoscope.
           | 
           | TIOBE index shows C has lost 62% of its users in 2016-2018,
           | then almost tripled in popularity next year, and then again
           | lost almost half of its users.
           | 
           | Do you think such swing of popularity is possible for such an
           | established slow-moving language? I don't think so -- it just
           | shows how far TIOBE can diverge from reality, and that the
           | error bars on the index should be +/- 50%. A few % blip means
           | nothing. TIOBE is measuring rollouts of new Google search
           | algorithms, not language popularity.
        
         | aardvark179 wrote:
         | Huge amounts of software are "legacy" but built with perfectly
         | modern tool chains and will support c23 just fine. Even for
         | large bits of software which have been mostly rewritten you'll
         | often find core libraries that are still actively developed but
         | have never been ported away from C.
        
         | pkrumins wrote:
         | We all use C because it works and we love to get things done.
        
           | drran wrote:
           | Not all of us use C, because it's very easy to create
           | security holes in C. For example, web browsers are using slow
           | JavaScript just because it memory safe.
        
         | sgt wrote:
         | Sounds like you're not really in touch with the real word. C
         | has many benefits and it is super practical. Yes, you can write
         | unsafe code, but safety isn't always your #1 priority. There
         | are also tools you can use to identify issues, which will
         | mitigate risks.
        
           | Koshkin wrote:
           | The truth is, C is merely a historical artifact, one step
           | above the PDP-11 assembly, created in order to make the UNIX
           | source code portable. It has transcended its original
           | purpose, and with it being elegant and simple as it is, I
           | would still never trust it to run a pacemaker.
        
           | KnobbleMcKnees wrote:
           | I'm really starting to believe that there's a cohort of
           | modern programmers that only see programming languages in
           | terms of the high level syntactical features they provide.
           | 
           | The logic of it is something like: I write the code, I run a
           | command written using similar code, scenes deleted, my
           | program runs and my IDE tells me if there are problems in my
           | code.
           | 
           | This is sometimes defined as the difference between
           | developers and engineers, but I don't really buy the analogy
           | because they're mostly highly competent and able to build
           | solid and principled architecture into their software.
           | 
           | This is the only reason I can summise that educated
           | programmers would say something like C is irrelevant.
           | 
           | I guess not everyone needs to have a depth of understanding
           | of the platforms that underly their languages of choice, but
           | - as demonstrated here - it certainly doesn't inform the
           | future of languages when they are inherently tied to their
           | ability to integrate with different hardware and OSs.
        
             | pjmlp wrote:
             | It was already irrelevant when using MS-DOS with Turbo
             | Pascal/Modula-2/Basic compilers, or Mac OS (originally
             | written in Object Pascal/Assembly).
             | 
             | It was UNIX industry adoption, followed by GNU Manifesto
             | that made to more relevant than it should ever have been.
        
       | tpoacher wrote:
       | For all of us that follow an "I do not want to log in to twitter"
       | philosophy, can someone here please post an alternative link?
       | 
       | Incidentally, I'm glad Twitter now blocks you from reading if not
       | signed in. I'm hoping this will encourage the use of
       | alternatives.
        
         | sva_ wrote:
         | I'm not signed in and read it fine. My uBlock filters are
         | twitter.com##[id^="layers"] >
         | [class^="css-"]:has([dir^="auto"]):not(:has([aria-
         | expanded])):has(a[href^="/"]):has-text(/Log in|Sign Up/)
         | twitter.com##html[dir]:style(overflow: auto !important;)
        
         | sebow wrote:
         | There is indeed nitter.I also recommend using an extension for
         | general redirecting.A popular one I use with presets for big
         | sites is Privacy Redirect (ff) but there are also ones for that
         | allow customization (Redirector for example, also ff).
        
         | deadmercury wrote:
         | Use nitter.net
         | 
         | https://nitter.net/__phantomderp/status/1494884135688626180
        
       | sys_64738 wrote:
       | It used to be that every new language starts off with a
       | translator to C. Not sure if that's the case nowadays.
        
         | dragonwriter wrote:
         | > It used to be that every new language starts off with a
         | translator to C.
         | 
         | No, it really never was that way, though there were some
         | languages (especially ones that started as C plus some
         | additional features, like C++ and Obj-C) that did that.
        
         | qayxc wrote:
         | With the advent of LLVM that's not common anymore.
         | 
         | Bootstrapping can be done in pretty much any language nowadays.
        
           | pjmlp wrote:
           | Neither it was common before, Objective-C, C++, Eiffel are
           | probably the only known ones with mainstream market share
           | that actually went via the compile to C as initial
           | implementation.
        
         | pjmlp wrote:
         | Not really, some did follow that path.
        
       | cpeterso wrote:
       | Another nice convenience: a new _#elifdef_ preprocessor directive
       | to replace longhand _#elif defined()_.
       | 
       | https://en.cppreference.com/w/c/23
        
       | pjmlp wrote:
       | Finally C catches up with Algol 60 boolean types, it only took 60
       | years.
       | 
       | Maybe in another 60 it will get proper strings and arrays.
        
         | moralestapia wrote:
         | >Maybe in another 60 it will get proper strings and arrays.
         | 
         | If you think this is missing, there's a big chance you don't
         | "get" C.
         | 
         | Also, if you don't know how to properly emulate strings in a
         | safe way in C nowadays (for which plenty of code sample and
         | librariesexist), your skills with the language are quite poor.
        
           | mhh__ wrote:
           | Adding so-called fat pointers to C that could be bounds
           | checked would probably instantly eliminate a large fraction
           | of _all_ security issues.
           | 
           | Of course, you can emulate these yourself, it's just a struct
           | but not everyone does.
        
             | Findecanor wrote:
             | C99 introduced variable-length array _parameters_ and
             | variable-length array _pointers_ together with variable-
             | length arrays (VLA). These take another parameter or
             | variable as a length-parameter. These became optional in
             | C11 together with VLAs (for some reason) but are supposed
             | to again become mandatory in C23. However (yet, for some
             | reason) the pointers can (in the latest published draft,
             | still) only be inside procedures: not in structs or in
             | global variables.
             | 
             | I think it would not be impossible for a C compiler to
             | detect and produce a warning if an index used with such an
             | array-pointer is not checked against the array-pointer's
             | length variable.
             | 
             | This would not make bounds-checks automatic, but the use of
             | these types could make compilers point out when bounds are
             | not checked or checked incorrectly.
        
             | flohofwoe wrote:
             | Adding opaque builtin struct types to C would be kind of a
             | big deal though and would probably creep into other parts
             | of the language and interact with them in unexpected ways.
             | Features like fat pointers, slices, builtin dynamic
             | arrays/strings or tagged unions would all require builtin
             | opaque structs. This would be a whole different language
             | (closer to Zig).
        
               | mhh__ wrote:
               | It really wouldn't be that hard to do. The syntax would
               | be trivial, and the whole point is that you want it to
               | creep so people actually use them.
               | 
               | There's no overhead to doing it, but you save a bunch of
               | bugs earlier, all for stopping conflating arrays with
               | pointers, which is something not much code does these
               | days anyway
        
           | pjmlp wrote:
           | I surely get C, having to deal with its casualties in
           | DevSecOps.
           | 
           | I have been "getting" C since 1992, across Xenix, DG/UX, HP-
           | UX, Solaris, AIX, FreeBSD, Linux, Amiga, Windows 3.x,.....
        
             | moralestapia wrote:
             | Well, then, you must know it's not really a big deal to
             | write code with proper memory checks.
        
               | dnautics wrote:
               | It's a big deal, you need about 1/3 of sel4 proofs
        
               | pjmlp wrote:
               | I have found yet another C expert.
               | 
               | https://www.cvedetails.com/vulnerability-
               | list/opmemc-1/memor...
        
               | coldtea wrote:
               | If you think that, then you really don't get C - not as
               | in "it's intents", but as in its actual history and
               | repurcursions...
        
             | nec4b wrote:
             | You once claimed C requires UNIX like OS to run.
        
               | coldtea wrote:
               | And he was right. He didn't mean it as a statement of
               | fact (which would be wrong, and he already knew it).
        
               | nec4b wrote:
               | No he was definitely wrong. Ask any C developer.
               | 
               | His comment:
               | https://news.ycombinator.com/item?id=20828974
        
               | pjmlp wrote:
               | I claim it yet again on this very comment.
               | 
               | Without UNIX spreading with its free beer into
               | universities, C would have been a footnote on the history
               | of system programming languages.
        
               | nec4b wrote:
               | Nope in the above comment you claim something else.
               | 
               | Here is where you claim C requires UNIX like OS:
               | 
               | https://news.ycombinator.com/item?id=20828974
               | 
               | Let me tell you, in embedded development we run C on bare
               | metal or under RTOS. There is no UNIX in sight. And the
               | code is portable to many CPU architectures.
        
               | pjmlp wrote:
               | A snowflake RTOS without POSIX, call me amazed.
        
               | nec4b wrote:
               | I'm happy you learned something.
        
               | tialaramex wrote:
               | Much more importantly, without UNIX and free beer TCP/IP
               | there's a fair chance the Internet isn't the Network and
               | none of this (gestures at HN and the Web) happens. That's
               | a much bigger impact than C which is just a programming
               | language, even if you count the influence of NUL-
               | terminated strings, and all the semi-colon languages
               | (including even Javascript and Rust, which are very
               | different from C but preserve the enthusiasm for semi-
               | colons) the Internet as Network makes more difference.
               | 
               | In particular it's possible X.25 could have won. JANET
               | (the tertiary education network in the United Kingdom)
               | was exclusively doing X.25 until 1991, when it tries an
               | experiment offering IP. Unsurprisingly free beer TCP/IP
               | offers a cornucopia of interesting new toys and sites are
               | very enthusiastic about JIPS (the experimental IP
               | service) so that by 1992 the IP service is no longer an
               | experiment but the primary service, with X.25 maintained
               | only until 1997.
               | 
               | You do get the Network anyway of course, that's what
               | everything is leading up to after Shannon, but you
               | probably get an X.25 flavoured Network instead of the
               | Internet, or some other system coming from another
               | direction, and broad deployment might have been delayed
               | into the early 21st century rather than the 1990s
               | depending on exactly how things work out. Stallman's GNU
               | project doesn't happen, Tim's toy hypermedia system
               | either doesn't exist or is a small inconsequential
               | experiment largely unknown outside hypermedia fanatics,
               | and Linus Torvalds probably doesn't make an operating
               | system kernel for his 386 microcomputer. It's a very
               | different environment, C is small potatoes by comparison.
        
         | nec4b wrote:
         | C must be really amazing compared to Algol than. It powers
         | today's computing infrastructure without having proper boolean
         | type. Are there any widely used applications written in Algol?
        
           | bitwize wrote:
           | The Burroughs MCP operating system and some applications
           | written on top of that. In fact, I believe that was the very
           | first OS to be written entirely in a high-level language.
           | 
           | MCP is not today widely used in the same way, say, React or
           | Linux is, but businesses used and depend on it such that it's
           | still sold and supported, as Unisys ClearPath MCP.
        
             | User23 wrote:
             | I've heard that Burroughs had an absolutely world class
             | engineering team in their heyday.
        
           | pjmlp wrote:
           | UNIX free beer, hard to beat.
        
             | nec4b wrote:
             | You do realize there is a lot of C code out there which has
             | nothing to do with UNIX. Although I do remember when you
             | once claimed C requires UNIX like OS to run. :)
        
               | Koshkin wrote:
               | Well, UNIX is surely responsible for C becoming popular
               | (if not its being a thing in the first place).
        
               | nec4b wrote:
               | I'm not arguing that it is not? It's funny though how
               | many people saw value in C but not in Algol. Maybe C has
               | something going for it?
        
               | pjmlp wrote:
               | Free beer alongside a free beer OS, instead of paying
               | thousands of dollars for timesharing OSes like VMS.
        
               | nec4b wrote:
               | I know you keep repeating it. You are conveniently
               | ignoring plenty of other commercial OSs and languages
               | which were successful.
        
               | pjmlp wrote:
               | UNIX is to C like the Web is to JavaScript.
               | 
               | JavaScript also runs outside of the browser nowadays, so
               | what.
        
               | nec4b wrote:
               | I don't know what are you trying to say? How does this
               | follow from the parent post?
        
               | pjmlp wrote:
               | It follows that the Web made JavaScript unavoidable, then
               | nodejs made it available everywhere else.
               | 
               | Likewise UNIX made C unavoidable in systems programming
               | for timesharing servers, eventually like JavaScript
               | outgrew the browser, certain people wanted to run C in
               | their microcomputers.
        
               | nec4b wrote:
               | I don't disagree with you on C being popular because of
               | UNIX. I do disagree if you believe this is the only
               | reason why it still enjoys popularity. And you are
               | selling the UNIX authors short if you think they chose C
               | just for the fun of it.
        
         | Koshkin wrote:
         | Then it would become Algol, wouldn't it?
        
           | pjmlp wrote:
           | So many features still missing.
        
       | belter wrote:
        
       | sgt wrote:
       | Based on another thread - I think the following topic should be
       | an interesting one for HN to chew on: If someone wanted to write
       | systems type of programming (whether it be embedded or Unix tools
       | or even writing a library), should they go for C (C23) or Rust
       | today?
        
         | mhh__ wrote:
         | D is a better modern C than Rust.
         | 
         | Rust is very nice, but if you just want a safer C that will
         | actually make you more productive versus less productive until
         | you understand how rust wants you to program then D is a better
         | fit.
        
           | Koshkin wrote:
           | Agree. "A better C" than C++ claims to be.
        
         | adrianN wrote:
         | I don't think that can be answered in general. It depends on
         | what exactly you want to do and the maturity of the libraries
         | in that area, and how security critical your application is.
        
           | dureuill wrote:
           | > the maturity of the libraries in that area,
           | 
           | While true for C++ which is not very interoperable, C being
           | very interoperable means that there is no advantage into
           | using a C API from C rather than from Rust.
           | 
           | > how security critical your application is.
           | 
           | Rust also has productivity and general "correctness"
           | advantages that go beyond security (although yes that alone
           | is a factor)
        
         | pkrumins wrote:
         | Definitely C!
        
         | bruce343434 wrote:
         | I'm going for C, because I am experienced with C and despite it
         | being more tedious, with having to do everything yourself, I
         | stick with it because the compile times, and in fact the
         | compile process, are so much faster and simpler. I really enjoy
         | the direct feedback I can get. I considered C++ but that too
         | had terrible compile times. Ideally a debug build should simply
         | not take longer than 100ms for a codebase that isn't even
         | 5KLoc, and only C seems to be able to offer that experience.
        
           | gefhfffh wrote:
           | I get that the compile process is faster, but simpler?
           | 
           | In my experience, the compile process usually consists of
           | "cargo build"
           | 
           | A advantage of Rust is that usually you spend way less time
           | debugging, because the compiler prevents many mistakes from
           | compiling in the first place.
        
             | bruce343434 wrote:
             | I have an IDE with clang-lint and I find that it can spot
             | pretty much every mistake. It can even detect some lifetime
             | issues. Other than that my programming style is very much
             | pass-by-value, trust the compiler to inline it, so the
             | typical memory safety issues are simply not relevant to me.
        
               | pornel wrote:
               | Pass-by-value and let LLVM clean it up is also the
               | idiomatic Rust way. rust-analyzer is pretty good for IDE
               | integration, and it will catch way more than clang-lint
               | (global lifetime analysis with guaranteed correctness,
               | not just best-affort local, and thread safety/data
               | races).
               | 
               | Regarding compile times, Rust has a different approach.
               | Instead of a fast cycle of run and see if it broke, it's
               | more of following compiler nags until the program is
               | correct and runs on the first try. Incremental (cached)
               | compile times aren't too bad these days.
        
               | gefhfffh wrote:
               | Before I tried Rust (I got sick of it and the slow
               | progress of Herb Sutter's research), I have used CLion
               | with clang-tidy and had plenty of memory issues going
               | undetected.
               | 
               | Needless to say I didn't restrict myself to pass-by-value
               | (compatible -> structs with ptrs are problematic as well)
               | style, which seems quite restrictive
        
               | pjmlp wrote:
               | With current ISO C++ velocity and the stance to keep
               | doing language evolution in person meetings, I don't
               | think Herb's proposals will ever come to be, and even if
               | they do, it won't matter when they most likely can only
               | make it post-ISO C++26 with best efforts.
        
           | flyinglizard wrote:
           | Why does it matter if compile time is 100ms or 300ms? At even
           | a second, that's going to be so negligible in the context of
           | code-compile-debug work. Especially if something like a flash
           | download is involved.
        
             | bruce343434 wrote:
             | 0. it is a noticeable delay and impinges my momentum
             | 
             | 1. A flash download is not involved
             | 
             | 2. I hardly debug. I seem to be in a minority here, but my
             | linter really does catch pretty much everything. I don't
             | blindly write code, I always ponder my approach first.
             | 
             | So basically, the compile times pull me out of the flow.
        
               | zh3 wrote:
               | Very much with you on this one. Even with 50k+ LoC a
               | 'make clean;make' takes less than a second (with help
               | from ccache and a RAM disk). It effectively gets the
               | compiler out of the way and keeps the thought processes
               | continuous.
               | 
               | One trick I like is to have a 2nd terminal watching the
               | file(s) I'm editing, triggering a make/run on each save;
               | building and running is then a single keypress away:-
               | while [ 1 ]; do       inotifywait -e move_self foo.c
               | cc foo.c -o foo && ./foo # or 'make && ./foo'       done
        
             | flohofwoe wrote:
             | The compilation time difference between C and Rust for
             | nontrivial projects is much bigger than 3x.
        
               | truffdog wrote:
               | Are there features you can ban in your style guide to
               | prevent serious compile time problems?
        
             | OJFord wrote:
             | Are your rust builds really that fast? Wth am I doing
             | wrong! I'd love to measure it in seconds.
        
               | jamincan wrote:
               | It's slow for me, but I'm not working on a very powerful
               | machine.
               | 
               | That said, cargo check is fast, and my general experience
               | with Rust is that it generally works once it compiles.
               | People getting into more advanced features might have
               | different experiences.
        
           | CyberRabbi wrote:
           | I'm going for C because programming language choice is a
           | matter of personal preference in essence and Rust annoys me.
        
             | sgt wrote:
             | How does it annoy you? Development velocity, creativity
             | hinderance?
        
           | dureuill wrote:
           | You could get productive in Rust in 3 months max, and then
           | the productivity gains would quickly outweigh the initial
           | investment
        
             | donkarma wrote:
             | Rust code takes longer to write than C code
        
               | pornel wrote:
               | It does for a novice. But once you learn Rust, it's
               | actually quite productive. Rust has proper collections,
               | strings, iterators, automatic (but not GC) memory
               | management, error propagation, etc. This eliminates a lot
               | of busywork, and makes Rust "denser", so you write less
               | code, but get more done.
        
               | hyperman1 wrote:
               | No, the greenfield coding phase of Rust will always take
               | longer than the same code in C: Rust will require you to
               | think things through, while C by default accepts any
               | morass of half-defined code.
               | 
               | The eventual rust code+debug+maintain speed will be
               | higher than the equivalent C speed, for the same reason.
               | 
               | This means that rust is slower for vanity projects that
               | won't be used in practice, or for low quality products
               | with an attitude a la hack it- ship it - hide for
               | customers - start next mess. The scary part: this is
               | actually an existing corner of our market.
        
               | dureuill wrote:
               | My experience is mainly with C++, but from my own
               | evaluation I'm x2 to x3 more productive overall in Rust
               | than in C++. The reasons are a simpler build system that
               | makes using the ecosystem faster, more expressive type
               | system (iterators with combinators, sum types), the
               | safety part that allows to not accidentally introduce UB
               | and to not waste time with static and runtime analysis,
               | shortening debug and review time. This compounds over
               | time to give a better maintenance time.
               | 
               | I don't have a similar evaluation for C <-> Rust, but I
               | suspect the result would be even more skewed in Rust's
               | favor: sure, you might be writing individual lines faster
               | in C, but the lack of iterators, generics, traits and
               | RAII, and the relative difficulty to use dependencies
               | means that you will waste a lot of time reinventing the
               | wheel, often suboptimally.
        
               | drran wrote:
               | Total time of <<coding + debugging>> (development time)
               | is shorter for safe Rust, because Rust eliminates few
               | classes of errors. Unsafe Rust and C are same, but Rust
               | have better abstractions (match operator, Rust enum's,
               | typed macros, etc.)
        
         | pjmlp wrote:
         | Neither, unless we are speaking of kernel and drivers kind of
         | systems programming, in which case I would pick Rust.
         | 
         | For anything else, a language with automatic memory management.
        
           | Koshkin wrote:
           | I wish D was more widely used, as it seems to be good as a
           | systems language, too.
        
             | pjmlp wrote:
             | Me too, unfortunately the lack of focus has allowed the
             | competition to step in, so at this point it is hard to tell
             | what would be the killer application that can make it take
             | off.
        
         | dureuill wrote:
         | In general, I think they should go for Rust. See [1].
         | 
         | Now, embedded is a special case. You need platform support, and
         | possibly certification, none of which are a given in Rust
         | today. Arguably, not in C23 either at the moment, though.
         | 
         | [1]: http://cliffle.com/blog/prefer-rust/
        
       | [deleted]
        
       | childintime wrote:
       | > In its London 2019 meeting, WG14 has found consensus to elevate
       | false and true to proper keywords.
       | 
       | The committee settled this over a beer, or some other substance?
       | Because the elevation to a proper type is opportunistic at best,
       | and against the spirit of C at worst. Next people celebrate this
       | with the use of capslock.
       | 
       | The futility of it all blows my mind :C
        
         | duskwuff wrote:
         | The "bool" type, as well as defines for "true" and "false",
         | already existed in <stdbool.h> [1]. What these proposals [2]
         | intend to change is making them real keywords, rather than
         | macros which expand to _Bool and appropriate integer values.
         | 
         | [1]:
         | https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/st...
         | 
         | [2]: http://www.open-
         | std.org/jtc1/sc22/wg21/docs/papers/2021/p231... and
         | http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p231...
        
         | jb1991 wrote:
         | > the elevation to a proper type is opportunistic at best, and
         | against the spirit of C at worst
         | 
         | Can you explain what you mean by this?
        
         | aliswe wrote:
         | > This is only one meeting. We have like 5 more before C23, and
         | only ~2 more before it's ISO Draft Ballot time
        
       | blastonico wrote:
       | > [dropped] Representations for signed integers other than two's
       | complement
       | 
       | May I assume that there won't be signed int undefined behavior
       | after C23? INT_MAX + 1 == INT_MIN?
        
         | Someone wrote:
         | I doubt it, and wouldn't want it. It would break all kinds of
         | optimizations. For example, with wrapping
         | for(int i = 0; i <= m; i++) { foo(); }
         | 
         | Wouldn't terminate if _m = INT_MAX_. That means compilers
         | either have to special-case that value, or can't use the loop
         | instructions of some CPUs (M68000 has "decrement and branch if
         | larger than zero", for example)
         | 
         | Also, with wrapping, _a[i]_ and _a[i+1]_ aren't guaranteed to
         | be adjacent. That can make auto-vectorisation difficult.
        
           | hfsrgbcfuknbft wrote:
           | Those things are very subtle and complex, so I'm not 100%
           | sure, but I think your first example is not great:
           | For example, with wrapping                      for(int i =
           | 0; i <= m; i++) { foo(); }                  Wouldn't
           | terminate if m = INT_MAX.
           | 
           | This is undefined behavior in the current standard when m =
           | INT_MAX. The condition i <= m is always true and i will
           | overflow. So it could result in an infinite loop (or worse).
           | AFAICT, with wrapping signed ints, it would infinite loop but
           | at least not yield UB?
        
             | Someone wrote:
             | Yes, for _m = INT_MAX_ and wrapping signed int, it is
             | undefined behavior.
             | 
             | Because of that, the compiler is allowed to assume _m [?]
             | INT_MAX_ , and that can mean it can generate more efficient
             | and/or smaller code.
             | 
             | Assuming _m [?] INT_MAX_ isn't (considered to be [1]) a big
             | loss because chances are the programmer who wrote that
             | didn't intend to write an infinite loop.
             | 
             | [1] of course, is an opinion, but it's the opinion the
             | standards writers have had for decades.
        
       | pwdisswordfish9 wrote:
       | > Oh, and a big deal: true/false are KEYWORDS NOW, and all of the
       | bool/thread_local/etc. are all KEYWORDS NOW!!!!
       | 
       | Why does it even matter? I could take true and false to be an
       | improvement (having them as macros expanding to int literals had
       | its problems, but even for that one I would not mind _True and
       | _False at all), but the rest? Who cares? It's literally the least
       | significant change.
        
       ___________________________________________________________________
       (page generated 2022-02-19 23:01 UTC)