Most active commenters
  • pjmlp(5)
  • f1shy(4)
  • tjoff(4)
  • com2kid(3)
  • adamrezich(3)
  • AlotOfReading(3)

←back to thread

The C23 edition of Modern C

(gustedt.wordpress.com)
397 points bwidlar | 43 comments | | HN request time: 0.002s | source | bottom
Show context
belter ◴[] No.41850897[source]
Important reminder just in the Preface :-)

Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up"

replies(6): >>41850960 #>>41851047 #>>41851166 #>>41851693 #>>41853183 #>>41855660 #
1. pjmlp ◴[] No.41850960[source]
Specially 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.
replies(3): >>41851031 #>>41851082 #>>41851268 #
2. Spivak ◴[] No.41851031[source]
I 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.
3. com2kid ◴[] No.41851082[source]
Perfectly 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.

replies(2): >>41851140 #>>41852515 #
4. f1shy ◴[] No.41851140[source]
What would be an example of "simple OO here and there" that cannot be done cleanly in plain C?
replies(6): >>41851225 #>>41851244 #>>41851407 #>>41851799 #>>41851998 #>>41854294 #
5. raluk ◴[] No.41851225{3}[source]
RAII
replies(2): >>41851243 #>>41851451 #
6. f1shy ◴[] No.41851243{4}[source]
Is RAII Object orientation? I thought it was an idiom of C++ by Stroustrup.
replies(1): >>41851991 #
7. adamrezich ◴[] No.41851244{3}[source]
Namespaces, methods.
replies(1): >>41851261 #
8. f1shy ◴[] No.41851261{4}[source]
Namespaces is not object orientation, is it? Am I missing something? You can place functions (methods) inside of structs in C23, can't you?
replies(3): >>41851286 #>>41851339 #>>41851481 #
9. flohofwoe ◴[] No.41851268[source]
Funny because for a long time the Microsoft MSVC team explicitly recommended compiling C code with a C++ compiler because they couldn't be arsed to update their C frontend for over two decades (which thankfully has changed now) ;)

https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-an...

replies(2): >>41851659 #>>41852439 #
10. staunton ◴[] No.41851286{5}[source]
On a high level, "object orientation" means you think of your code as representing the state and interactions of objects. You can equally well do this in assembly. If you think of some namespace as a "singleton object" then that's what it is.

I guess what you're really asking is what are the best or most common ways to do OO in C?

replies(1): >>41851403 #
11. adamrezich ◴[] No.41851339{5}[source]
Correct, and you did ask specifically for OO things, but I thought I'd list namespaces too as far as “C++ things you might use when writing C-like C++ code”.

Another big one that I always forget C still doesn't support is function overloading.

replies(1): >>41852319 #
12. f1shy ◴[] No.41851403{6}[source]
Oh. I learned that object orientation is primarily a way to structure data and code, such that the data is encapsulated with the code that works on it, in so called objects. So an Object is the Data, plus the functions that work on the data, an ensure that some invariants are kept. In OO parlance, that code gets executed by sending messages (calling methods).

Where can I find something about objects being "think of your code as representing the state and interactions of objects" honesty totally new to me.

So no, certainly I'm not asking ways to do OO in C. But it seems to be more definitions of object orientation as I thought...

replies(2): >>41851523 #>>41851677 #
13. bobmcnamara ◴[] No.41851407{3}[source]
Templating on pixel classes so that a blitter builds all supported pixel paths separately and inlines them.

Yes you can do it less cleanly with macros or inline functions. But you can't do it performantly with struct and function pointers.

14. tjoff ◴[] No.41851451{4}[source]
The killer feature of RAII is when combined with exceptions. But sneaking in exceptions in an embedded C project isn't something I'd encourage or recommend.

C++ imo doesn't offer anything compelling for the embedded usecase. Especially not considering all the footguns and politics it brings.

You can of course be strict and diligent about it but if you are you are pretty much just writing C anyway. Better to do it explicitly.

Allowing the use of the C++ standard library has been one of my biggest regrets (not that it was my decision to make, I fought it).

replies(2): >>41852178 #>>41852332 #
15. int_19h ◴[] No.41851481{5}[source]
You can handcode vtables in C, just as you can handcode loops in assembly (i.e. it works but it's verbose, not particularly readable, and brings more footguns).

But why would you do that if you have an instrument that lets you work at the same level as C, but with methods provided as a proper abstraction that maps exactly to what you'd have written yourself anyway?

replies(1): >>41852301 #
16. int_19h ◴[] No.41851523{7}[source]
There's no clear definition of what OO is, so the best you can do pragmatically is look at mainstream languages that are broadly recognized as OO and try to deduce the commonalities.

If you do that, you'll notice that, for example, encapsulation is not a part of that de facto definition, because languages like Python and (until recently) JavaScript lack it, despite being considered OO.

Indeed, the only two things that appear to be consistently present in all OO languages are: 1) some notion of object identity as distinct from object state, and 2) runtime polymorphic dispatch.

17. rdtsc ◴[] No.41851659[source]
That thing always baffled me, this huge company building a professional IDE couldn't figure out how to ship updates to the C compiler.

> it is hard to say no to you, and I’m sorry to say it. But we have to choose a focus, and our focus is to implement (the standard) and innovate (with extensions like everyone but which we also contribute for potential standardization) in C++.

I mean, yeah if it came from a two member team at a startup, sure focus on C++, understandably. But Microsoft, what happened to "Developers! Developers! Developers!"?

replies(3): >>41851811 #>>41851984 #>>41852459 #
18. epcoa ◴[] No.41851677{7}[source]
> Where can I find something about objects being "think of your code as representing the state and interactions of objects" honesty totally new to me.

I’m scratching my head how you think this is materially different than what you described in your first para. s/state/data and s/interactions/methods.

If anything though I would say the GP is more aligned with the classic definition as it highlights the focus is more on the messages (interactions) themselves rather than the implementation.

19. ◴[] No.41851799{3}[source]
20. Jtsummers ◴[] No.41851811{3}[source]
It's not baffling, it's remarkably consistent. They implemented Java as J++ and made their version incompatible in various ways with the standard so it was harder to port your code away from J++ (and later J#). They implemented things in the CSS spec almost exactly opposite the specification to lock people into IE (the dominant browser, if you have to make your site work with 2+ incompatible systems which will you focus on?). Not supporting C effectively with their tools pushed developers towards their C++ implementation, creating more lock-in opportunities.
21. AlotOfReading ◴[] No.41851984{3}[source]
Funnily enough, the intellisense parser does support C syntax because it's using a commercial frontend by edison under the hood. MSVC's frontend doesn't.
22. runevault ◴[] No.41851991{5}[source]
It doesn't necessarily have to be OO no. Rust uses RAII and it uses traits instead of traditional OO style inheritance etc. You do need something like destructors/drop trait for it to work as far as I know though.
23. cozzyd ◴[] No.41851998{3}[source]
CRTP?
24. AlotOfReading ◴[] No.41852178{5}[source]
C++ offers lots of compelling things for embedded use cases, like enum classes (finally fixed in C23), constexpr, std::optional, namespaces, and atomics/generics that are much smaller dumpster fires.

There's an effort to extract the good parts and make it work for embedded use cases or even bring them into C. Khalil Estelle on WG21 has been working on an experimental, deterministic runtime for exception handling, to give one example. Constexpr is an example of the latter that's now showing up in C23.

replies(1): >>41852427 #
25. uecker ◴[] No.41852301{6}[source]
I don't know, I never found the "proper abstraction" be more than irrelevant syntactic sugar. And the cost of C++ is that you end up putting everything in the header (IMHO the biggest design flaw of the language) and then compile time start to get long....
26. uecker ◴[] No.41852319{6}[source]
Function overloading is a feature that makes code less self-documenting without providing any meaningful value. Operator overloading is more interesting, because you can build you domain language with nice syntax. But I also tend to think that this is not really worth it.
replies(1): >>41853276 #
27. kccqzy ◴[] No.41852332{5}[source]
There are a lot of large C++ shops that purposefully disable exceptions and yet still use RAII usefully. It's so useful that in many C codebases you see people using RAII. For example Gtk has g_autoptr and g_autofree.

One of the most compelling things C++ offers to embedded use case is moving runtime initialization to compile-time initialization by liberally using constexpr functions. You literally ask the compiler to do work that would otherwise be done at runtime.

replies(1): >>41853043 #
28. tjoff ◴[] No.41852427{6}[source]
I don't disagree, but these are in the ~2% convenience at most. With the huge baggage of including C++ in a project. The cost of learning C++ easily outweighs all those benefits. If you happen to have a proficient C++ team (that actually know embedded), go for it!
replies(1): >>41852592 #
29. pjmlp ◴[] No.41852439[source]
Yeah, 12 years ago, when governments couldn't care less about nation state cyberattacks, and Microsoft was yet to be called by the Congress to testify on their failures.
30. pjmlp ◴[] No.41852459{3}[source]
It was on purpose, Microsoft was done with C, the official message was to move on to C++.

The change of heart was the new management, and the whole Microsoft <3 FOSS.

replies(1): >>41852886 #
31. pjmlp ◴[] No.41852515[source]
Yeah, but one should provide C++ type safe abstractions on top.

Just like one doesn't use Typescript to keep writing plain old JavaScript, then why bother.

32. AlotOfReading ◴[] No.41852592{7}[source]
Speaking more broadly than just the std implementation, but result types like optional shouldn't be a 2% convenience, they should be used in most function calls that return errors. Rust is the obvious example here.
replies(1): >>41853150 #
33. rdtsc ◴[] No.41852886{4}[source]
> It was on purpose, Microsoft was done with C

Indeed, and yet here we are with C23

> The change of heart was the new management, and the whole Microsoft <3 FOSS.

Yeah, agree. To me the turning point was when they created WSL.

replies(2): >>41855699 #>>41856495 #
34. tjoff ◴[] No.41853043{6}[source]
RAII is useful without exceptions yes. I guess it is the other way around. Exceptions are not useful without RAII (sorry not sorry most garbage collected languages ;)).

But without exceptions it is mostly syntactic sugar anyway.

If compile time initialization is the most compelling usecase I'll rest my case. Good feature, yes! Hardly worth switching language for.

35. tjoff ◴[] No.41853150{8}[source]
If you argue for Rust I'm all for it, arguably much less of a learning curve than C++ too.
36. adamrezich ◴[] No.41853276{7}[source]
In C++ where you have methods? Sure. It would be nice to have in C, though. But, alas, ABI compatibility.
37. com2kid ◴[] No.41854294{3}[source]
You can do anything in C that you want to. Of course one can make v-tables and all of that, and even do inheritance.

But having the "class" keyword is nice. Having built in support for member functions is nice.

Sometimes a person just wants the simplicity of C++ 2003.

(In reality I was working on a project where our compiler only supported C++ 2003 and we had a UI library written in C++ 2003 and honestly pure C UI libraries kind of suck compared to just sprinkling in a bit of C++ sugar.)

replies(1): >>41855255 #
38. throwaway2037 ◴[] No.41855255{4}[source]

    > You can do anything in C that you want to.
How about destructors?
replies(1): >>41856788 #
39. kragen ◴[] No.41855699{5}[source]
Microsoft didn't create C23 and they don't <3 FOSS. They're accepting that they have to deal with FOSS, but installing Windows will still make your Linux system unbootable until you fix it with a rescue disk, among numerous other unfriendly things they do.
replies(1): >>41855935 #
40. alexvitkov ◴[] No.41855935{6}[source]
I haven't seen Windows fuck up the EFI partition or delete the other entries in a while now. After installing it the machine will usually boot directly into it, but it should be just a toggle in the firmware to switch back to GRUB.
replies(1): >>41856064 #
41. kragen ◴[] No.41856064{7}[source]
That's an improvement! When did they fix that?
42. pjmlp ◴[] No.41856495{5}[source]
Microsoft doesn't take part on WG14, and MSVC only does up to C17 nowadays.
43. com2kid ◴[] No.41856788{5}[source]
You can obviously build any runtime system you desire in C, including one that parses and executes C code with additional features added in. The wisdom of doing this is questionable.

Though I've actually seen macro systems that do things akin to destructors, although less automatically.