17 ms·
The C23 edition of Modern C
- mococa 2y agoI wish auto in C was similar to auto in C++.
- bitbasher 2y agoReally looking forward to #embed, once the compilers catch up. Until then, Golang.
- enriquto 2y agoThis is not how C standards work. If it appears in the standard, it means that it is already implemented in some compilers (in that case, at least in gcc and clang).
- pjmlp 2y agoThat isn't really how it goes, that is how it used to be up to C99.
- enriquto 2y agoThanks for the correction! Do you know if there is a document from the standards body explaining the change in philosophy?
- MathMonkeyMan 2y agoI've heard something along the lines of "the standard is to define facilities that will be used in most programs, and to codify widespread existing practice." That was in the context of "I don't like this proposed feature," though. This was for C++, not C. A lot of stuff in the C++11 standard library was based on widespread use of Boost. Since then, I don't know. Also, were things like templates and lambdas implemented as compiler extensions before standardization? I don't know, but I doubt it. Maybe "we're a committee of people who will decide on a thing and we hope you like it" was always the norm in many ways.
- JonChesterfield 2y agoIt's a nuisance to implement the thing you want to add to the standard yourself. It's easier to ship it in the language and then complain at compiler devs that they're running behind the edge of progress. This interacts in the obvious way with refusing to correct mistakes after the fact for fear of breaking user code. I don't believe anyone has written a paper along the lines of "let's not bother with the existing practice part anymore", it's more an emergent feature of people following local incentive structures.
- rfl890 2y agoClang 19 has it.
- jpcfl 2y agoOr xxd --include <file> :)
- Keyframe 2y agoThe anti-Rust approach!
- f1shy 2y agoI do that with ld and objcopy: https://stackoverflow.com/questions/58815959/include-binary-data-files-into-compiled-binary-without-converting-to-hex-arrays https://stackoverflow.com/questions/58815959/include-binary-...
- accelbred 2y agoI end up using a .S asm file with .incbin directives to embed files. #embed would be much nicer
- JonChesterfield 2y agoIncbin works just fine from inline asm fwiw
- flohofwoe 2y agoInline assembly isn't supported for x86-64 and ARM on MSVC which unfortunately also means the incbin trick can't be used there anymore.
- belter 2y agoImportant reminder just in the Preface :-) Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up"
- pjmlp 2y agoSpecially relevant to all those folks that insist on "Coding C with a C++ compiler", instead of safer language constructs, and standard library alternatives provided by C++ during the last decades.
- Spivak 2y agoI mean as long as your goal is specifically to do that I think it's fine. Using a C++ compiler to compile a C program isn't that rare.
- com2kid 2y agoPerfectly valid to do if you need to interface with a large C code base and you just want to do some simple OO here and there. Especially if you cannot have runtime exceptions and the like. This is how I managed to sneak C++ into an embedded C codebase. We even created some templates for data structures that supported static allocation at compile time.
- enriquto 2y agoSo happy that we still get the dinosaur mascots! This is a good book.
- auggierose 2y agoTable of contents in the sidebar doesn't work properly for me when I click on an entry (in macOS Preview).
- bwidlar 2y agoI just test some links in the table of content, works fine for me. Using zathura pdf reader.
- Jtsummers 2y agoAlso works in Adobe and Firefox, but doesn't work in Chrome and Edge.
- f1shy 2y agoDoesn't work for me either... but I will not dismiss the book because of that.
- soegaard 2y agoSame here.
- channel_t 2y agoTable of contents is definitely broken right now.
- jumpman_miya 2y agoin example 1.1 i read that as 'tits_square' until i saw the output
- zkirill 2y agoI was going to ask if there is a good list of C books and then answered my own question. It categorizes _Modern C_ as Intermediate level. https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list https://stackoverflow.com/questions/562303/the-definitive-c-...
- emmanueloga_ 2y agoNote that this is not a complete list, fwiw. For example, I doesn't include "Effective C." [1]. I like "Effective C" over "Modern C" because it's more engaging ... "Modern C" is super rigorous and feels a bit like reading an annotated spec of the language, which is what an expert may need, but makes for a dull read for a casual C user like me. -- 1: https://nostarch.com/effective-c-2nd-edition https://nostarch.com/effective-c-2nd-edition
- xbar 2y agoI agree, but I think Modern C has good, structured recommendations that make it worth getting through at least once.
- rramadass 2y agoAlso see Fluent C: Principles, Practices and Patterns by Christopher Preschern.
- xbar 2y agoI like Modern C. I have reviewed it favorably in several places. I agree it is intermediate. I think 21st Century C by Ben Klemens and C Programming a Modern Approach by King are both more approachable alternatives as a modern C companions to K&R.
- ralphc 2y agoHow does "Modern" C compare safety-wise to Rust or Zig?
- renox 2y agoYou'd be surprised: Zig has one UB (Undefined Behaviour) that C doesn't have! In release fast mode, unsigned overflow/underflow is undefined in Zig whereas in C it wraps. :-) Of course C has many UBs that Zig doesn't have, so C is far less safe than Zig, especially since you can use ReleaseSafe in Zig..
- uecker 2y agoUB is does not automatically make things unsafe. You can have a compiler that implements safe defaults for most UB, and then it is not unsafe.
- ahoka 2y agoBy definition UB cannot be safe.
- marssaxman 2y agothis depends on your choice of definition for "safe"
- Maxatar 2y agoThe definition given by the C standard allows for safe undefined behavior.
- School-Cotton 2y agoSomething can be UB according to the standard, but defined (and safe) according to a particular implementation. Lots of stuff is UB according to the C or C++ standard but does something sensible in gcc and/or clang.
- duped 2y agoThat's implementation defined behavior, not undefined behavior. Undefined behavior explicitly refers to something the compiler does not provide a definition for, including "safe defaults."
- zerr 2y agoDo they still use 0-terminated strings/char* as the main string type? Is the usage of single linked lists still prevalent as the main container type?
- racingmars 2y ago> Do they still use 0-terminated strings/char* as the main string type? Of course, it's still C. > Is the usage of single linked lists still prevalent as the main container type? As far as I can remember, the C standard library has never had any functions that used linked lists. Nor are there any container types, linked lists or otherwise, provided by C. So I'd say this is a question about how people teach and use C, not related to the language -- or language spec version -- itself.
- KerrAvon 2y agoThe C standard library provides no recognizable container types, so there's no "main" anything.
- codr7 2y agoEmbedded linked lists are pretty cool though.
- ithkuil 2y agoaka intrusive linked lists
- EasyMark 2y agoI don’t think that will ever change. Will the possibly introduce a more modern string2 type? Maybe but it will probably be unlikely before 2050
- russellbeattie 2y agoWow, the use of attributes like [[__unsequenced__]], [[maybe_unused]] and [[noreturn]] throughout the book is really awful. It seems pretty pedantic of the author to litter all the code examples with something that is mostly optional. For a second I wondered if C23 required them.
- amomchilov 2y agoSuch is the issue with bad defaults. Opting into the sensible thing makes most of your code ugly, instead of just the exceptions.
- nimish 2y agoMy kingdom for fully specified, well defined portable bitfields.
- leonheld 2y agoOne of my favorite books ever.
- einpoklum 2y agoIt's only been a few years since I've come to feel I can rely on C compilers all supporting C99, for a library I'm maintaing [1]. And after a couple of years, sure enough - I get an issue opened asking for C89 compatibility because of some arcane embedded toolchain or what-not. So, C23? ... that's nice and all, but, let's talk about it in 20 years or so T_T [1]: https://github.com/eyalroz/printf https://github.com/eyalroz/printf
- jhatemyjob 2y agoCan someone link me to an article that explains why C is basically frozen at C99 for all practical purposes? Few projects worth talking about leverage features from C11 and newer
- pornel 2y agoC99 is still new! Microsoft tried to kill C by refusing to implement anything that wasn't also in C++. MSVC was 16 years late implementing C99, and implemented only the bare minimum. Their C11 implementation is only 11 years late. I suspect that decades of C being effectively frozen have caused the userbase to self-select to people who like C exactly the way it is (was), and don't mind supporting ancient junk compilers. Everyone who lost patience, or wanted a 21st century language, has left for C++/Rust/Zig or something else.
- uecker 2y agoMost of us liking a good language just did not use MSVC. I do not think many people who appreciate C's simplicity and stability would be happy with C++ / Rust. Zig is beautiful, but still limited in many ways and I would not use it outside of fun projects.
- pornel 2y agoI don't even use Windows, but I need to write portable libraries. Unfortunately, MSVC does strongly influence the baseline, and it's not my decision if I want to be interoperable with other projects. In my experience, Windows devs don't like being told to use a different toolchain. They may have projects tied to Visual Studio, dependencies that are MSVC-only or code written for quirks of MSVC's libc/CRT, or want unique MSVC build features. I found it hard to convince people that C isn't just C (probably because C89 has been around forever, and many serious projects still target it). I look like an asshole when I demand them to switch to whole another toolchain, instead of me adding a few #ifdefs and macro hacks for some rare nice thing in C. Honestly, paradoxically it's been easier to tell people to build Rust code instead (it has MSVC-compatible output with almost zero setup needed).
- kristianp 2y agoGCC support has been around since gcc 11 apparently. See table at (1). This is available in ubuntu 22.04. The page below also shows support for C26! 1) https://gcc.gnu.org/projects/cxx-status.html#:~:text=C%2B%2B23%20Support https://gcc.gnu.org/projects/cxx-status.html#:~:text=C%2B%2B...
- johnisgood 2y agoPersonally this[1] just makes C much more complicated for me, and I choose C when I want simplicity. If I want complicated, I would just pick C++ which I typically would never want. I would just pick Go (or Elixir if I want a server). "_BitInt(N)" is also ugly, reminds me of "_Bool" which is thankfully "bool" now. [1] guard, defer, auto, constexpr, nullptr (what is wrong with NULL?), etc. On top of that "constexpr" and "nullptr" just reeks of C++. That said, Modern C is an incredible book, I have been using it for C99 (which I intend to continue sticking to).
- cornstalks 2y ago> what is wrong with NULL? For starters, you have to #include a header to use it.
- zik 2y agoAnd it avoids the NULL == 0 ambiguity, allowing for better type checking.
- johnisgood 2y agoWell, I always include stdio.h which includes stddef.h that defines NULL as (void *)0.
- dhhfss 2y agoIn my experience, hardly any source files require studio.h stddef.h on the other hand is required by most to get size_t
- johnisgood 2y agoYou are right. Hereby I correct my parent comment: I talked about my own personal experience[1], but yeah, as you said, stddef.h is often required (and yes, often I do not need stdio.h, stddef.h is what I need) which defines NULL, which was my point. If it is often required, then it does not matter whether you have to include a header file or not, IMO. Just include the stddef.h header if you want to use NULL, similarly to how you include a header file if you want to use anything else, e.g. bool from stdbool.h. [1] I am not entirely sure in retrospect, actually, as I might be misremembering, but my point stands with or without stdio.h!
- israrkhan 2y agoMost important aspect of C is its portability. From small microcontrollers to almost any computing platform. I doubt that any new version of C will see that much adoption. If I want to live on cutting edge I would rather use C++2x or Rust rather than C. Am I missing something? What benefit this supposedly modern C offers?
- vitaminka 2y agothese features will eventually trickle down into the mainstream, kind of like C11 is doing at the moment also, unless you're targeting embedded or a very wide set of architectures, there's no reason why you couldn't start using C23 today
- bboygravity 2y agoOr in other words, for embedded and existing code: most use c99, some use c11 and nobody uses c23 until at least 10 years from now.
- dhhfss 2y agoThis depends on the platform. Many embedded systems are based on arm these days and have modern toolchains available. I cannot remember the last time I saw C99 used. C codebases generally use C11 or C17, and C++ code bases use C++20
- pjmlp 2y agoUnless you can vouch for the C++ compiler, the best C++ portable code can offer today is C++17. Also 8 and 16 bit embedded toolchains are certainly not on C11 / C17, they can hardly afford full C89.
- flohofwoe 2y agoSDCC is a niche C compiler for 8-bit CPUs and is more uptodate than MSVC ;P https://sdcc.sourceforge.net/ https://sdcc.sourceforge.net/ That's the nice thing with C: it's much easier for small teams to fully support than the latest C++ standards.
- musicale 2y agoI kind of like some of Metaware's high C extensions. https://news.ycombinator.com/item?id=41647843 https://news.ycombinator.com/item?id=41647843 https://news.ycombinator.com/item?id=38938402 https://news.ycombinator.com/item?id=38938402
- survivedurcode 2y agoContinuing to use a memory-unsafe language that has no recourse for safety and is full of footguns and is frankly irresponsible for the software profession. God help us all. By the way, the US government did the profession no favors by including C++ as a memory-unsafe language. It is possible to write memory-safe C++, safe array dereferencing C++. But it’s not obvious how to do it. Herb Sutter is working on it with CppFront. The point stands that C++ can be memory-safe code. If you make a mistake, you might write some unsafe code in C++. But you can fix that mistake and learn to avoid it. When you write C, you are in the bad luck shitter. You have no choice. You will write memory—unsafe code and hope you don’t fuck it up. You will hope that a refactor of your code doesn’t fuck it up. Ah, C, so simple! You, only you, are responsible for handling memory safely. Don’t fuck it up, cadet. (Don’t leave it all to computers like a C++ developer would.) Put C in the bin, where it belongs.
- fjfaase 2y agoThere are still applications (especially with embedded devices) where you do not dynamically allocate memory or might not even use pointers at all.
- purple-leafy 2y agoSkill issue
- pornel 2y agoIt's been a skill issue for 40 years. How long are we going to continue searching for those programmers who don't make mistakes?
- worksonmine 2y agoProgrammers make stupid mistakes in the safest languages too, even more so today when software is a career and not a hobby. What does it matter if the memory allocation is safe when the programmer exposes all user sessions to the internet because reading Dockers' documentation is too much work? Even Github did a variant of this with all their resources.
- tenderfault 2y agoany chance of getting a responsive TOC in any pdf reader whatsoever?
- kamaal 2y agohttps://www.manning.com/books/modern-c-third-edition https://www.manning.com/books/modern-c-third-edition
- johanvts 2y agoI payed for this on manning and they didn’t even release the final version yet. I guess I didn’t understand what I was buying, but I can’t help feel a bit cheated.
- sylware 2y agoI am worried where "official" C is going. Its syntax which is already too complex and already does too much, but that would require to "break" backward compatibility namely it would require "porting". But since it would be still "C" that amount of work should be close to "a bit" of "step by step" refactoring For instance, only sized types:u8...s64, f32, f64... no implicit casts except for void* and literals, no integer promotion, no switch, no enum, only one loop keyword (loop{}!), no anonymous code block, and no toxic attribute like "packed structure" which makes us lose sight of data alignment... no _generic, typeof, restrict, syntax based tls, etc... But we would need explicit atomics, explicit memory barriers, explicit unaligned memory access. Instead of adding and complexifying C to make writing a naive compiler more and more complex, long and a mouse and cat catchup "to the standard" tedious task, what should be done is exactly the other way around. In end, I don't trust C officials anymore, I tend to stick to C99, or even assembly (I am currently writing rv64 assembly I run an x86_64).
- eqvinox 2y ago> I tend to stick to C99, > […] But we would need explicit atomics, explicit memory barriers, […] You should read a change summary before complaining about bits missing from C99 that have in fact been added to C11. > […] no toxic attribute like "packed structure" which makes us lose sight of data alignment […] And you should also familiarize yourself with what's in actual ISO C vs. compiler extensions before complaining about bits that are in fact compiler extensions.
- sylware 2y agoI TEND to stick to C99 = usually C99 with very few bits of c11+ (usually the missing bits) and even some extensions (often related to ELF/object format). But I really try hard to minimize their usage. The pb is in ISO c11+ we got some of the missing stuff for modern hardware architecture, but also tons of tantrums (_generic, typeof, restrict....)
- eqvinox 2y ago> The storage order, the endianness, as given for my machine, is called little-endian. A system that has high-order representation digits first is called big-endian. Both orders are commonly used by modern processor types. Some processors are even able to switch between the two orders on the fly. Calling big endian "commonly used by modern processor types" when s390x is really the only one left is a bit of a stretch ;D (Comments about everyone's favorite niche/dead BE architecture in 3… 2… 1…)
- ondra 2y agoMIPS is still quite alive in consumer networking hardware.
- eqvinox 2y agoTrue - but at the same time, about half¹ of it is mipsel, i.e. in little-endian mode :). It's also in decline, AFAICS there is very little new silicon development. ¹ on the OpenWRT table of hardware
- tonetegeatinst 2y agoLearning MIPS assembly currently using mars and QtSpim. Any recommended hardware I should use for bare metal development messing around? Hopefully priced like a SBC like the raspberry pi. Want to move from making basic programs like adding, messing with functions, etc and bring my MIPS assembly up to a real hardware environment.
- AntoniusBlock 2y agoMany routers use the MIPS ISA and they can be rooted to get shell access. That's what I did with an old Netgear router, which was like a very low spec SBC. If you have a PS2 lying around, you could try that.
- throwaway19972 2y ago"Modern" doesn't mean "currently widespread".
- uvas_pasas_per 2y agoI've been using modern C++ for a personal project (a language interpreter) for the last year+. I constantly think of switching to C, because of the mental burdens of C++, and because of the problems with tooling (Visual Studio's IntelliSense still barely works, because I use C++20 modules), and compile times get ugly because of the way the language failures force so much into interfaces (even with modules). But on the flip side I've gotten so used to classes, member functions, generic programming (templates), namespaces... I may be hooked.
- fluoridation 2y agoI've been using C++ for the longest time, and I would never give up destructors to switch to C. For your particular use case, have you considered C#? VS works much more nicely with it.
- uvas_pasas_per 2y agoYeah, I did. I want something low level and cross platform, including mobile. I think when I tried the C# for iOS stuff, nothing worked. But it's probably too much VM/runtime for me anyway, for this project.
- fluoridation 2y agoFair enough. I would've used C++ as well.
- neonsunset 2y agoiOS C# is more or less fine, there is quite a bit of work done in .NET to make this better still. .NET 9 gains native Swift Library Evolution ABI support even - you can literally declare DllImports against public Swift APIs by simply annotating them with [typeof(CallConvSwift)], it's not as convenient as it sounds but it's only a matter of time when the tools like https://github.com/royalapplications/beyondnet https://github.com/royalapplications/beyondnet adopt this. It's going to get much better once MonoAOT is replaced with NativeAOT for all major publish modes for iOS.
- RantyDave 2y agoWait, C programmers now put the star on the left hand side? char* thing; // good char *thing; // bad This ... is awesome. As a C++ "native" I've always found the "star on the right" thing to be really horribly confusing.
- bloppe 2y agoOfc this has always been an option. In my C heyday I used to put a space on both sides of the star. It makes for a more consistent syntax when you have multi layer pointers with const at various layers. For example: // mutable pointer to mutable data: char * str; // Immutable pointer to immutable data: char const*const str; // Mutable pointer to an immutable pointer to a mutable pointer to immutable data: char const**const* strs;
- int_19h 2y agoGiven that putting it on the right reflects the actual syntax tree of the code, why do you find it "horribly confusing"? I mean, one can reasonably argue that C & C++ declarator syntax is itself horribly confusing because it doesn't read left-to-right. But it is what it is, so why pretend that it's something else?