Earlier quoted context omitted.
>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up" Where "mixing C/C++" is helpful: - I "mix C in with my C++" projects because "sqlite3.c" and ffmpeg source code is written C. C++ was designed to interoperate with C code. C++ code can seamlessly add #include "sqlite3.h" unchanged. - For my own code, I take advantage of "C++ being _mostly_ a superset of C" such as using old-style C printf…
C++ can seamlessly include C89 headers. The C library headers for libraries I write often include C11/C99 stuff that is invalid in C++. Even when they are in C89, they are often incorrect to include without the include being in an `extern "C"`.
The C23 edition of Modern C
61–70 of 360 posts
Re: The C23 edition of Modern C
#62Earlier quoted context omitted.
Because people choose to use pre-increment by default instead of post-increment? Why is that?
Why use this operator? Like most C and C++ features the main reason tends to be showing off, you learned a thing (in this case that there are four extra operators here) and so you show off by using it even if it doesn't make the software easier to understand. This is not one of those beginner -> journeyman -> expert cycles where coincidentally the way you wrote it as a beginner is identical to how an expert writes it…
void strcpy(char *s, char *t)
{
while (*s++ = *t++)
;
}
(straight from K&R) wouldn’t work without it.Re: The C23 edition of Modern C
#63Important reminder just in the Preface :-) Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up"
>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up" Where "mixing C/C++" is helpful: - I "mix C in with my C++" projects because "sqlite3.c" and ffmpeg source code is written C. C++ was designed to interoperate with C code. C++ code can seamlessly add #include "sqlite3.h" unchanged. - For my own code, I take advantage of "C++ being _mostly_ a superset of C" such as using old-style C printf…
The modern fmt-inspired std::print and std::println etc. are much nicer, preserving all the type checking but losing terrible ideas like stored format state, and localisation by default. The biggest problem is that today C++ doesn't have a way to implement this for your own types easily, Barry illustrates a comfortable way this could work in C++ 26 via reflection which on that issue closes the gap with Rust's #[derive(Debug)].
Re: The C23 edition of Modern C
#64Earlier quoted context omitted.
RAII
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 exp…
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.
Re: The C23 edition of Modern C
#65Earlier quoted context omitted.
>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up" Where "mixing C/C++" is helpful: - I "mix C in with my C++" projects because "sqlite3.c" and ffmpeg source code is written C. C++ was designed to interoperate with C code. C++ code can seamlessly add #include "sqlite3.h" unchanged. - For my own code, I take advantage of "C++ being _mostly_ a superset of C" such as using old-style C printf…
C++ can seamlessly include C89 headers. The C library headers for libraries I write often include C11/C99 stuff that is invalid in C++. Even when they are in C89, they are often incorrect to include without the include being in an `extern "C"`.
It takes a little bit of an effort to make a header work on C and C++. A lot less effort than making a single Python file work with Python 2 and 3.
Re: The C23 edition of Modern C
#66Earlier quoted context omitted.
Why would you use post increment by default? The semantics are very particular. Only on very rare occasions I need post increment semantics. And in those cases I prefer to use a temporary to make the intent more clear
People seem to mostly write a typical for loop ending with ; ++i){ But I write ; i++){ and seeing it the other way round throws me off for a minute, because I think, as you put it, why would you use those very particular semantics? But I guess this is only a semantic argument.
Re: The C23 edition of Modern C
#67Earlier quoted context omitted.
Namespaces is not object orientation, is it? Am I missing something? You can place functions (methods) inside of structs in C23, can't you?
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?
Re: The C23 edition of Modern C
#68How does "Modern" C compare safety-wise to Rust or Zig?
Modern C still promptly decays an array to a pointer, so no array bounds checking is possible. D does not decay arrays, so D has array bounds checking. Note that array overflow bugs are consistently the #1 problem with shipped C code, by a wide margin.
This isn’t strictly true, a C implementation is allowed to associate memory-range (or more generally, pointer provenance) metadata with a pointer.
The DeathStation 9000 features a conforming C implementation which is known to catch all array bounds violations. ;)
Re: The C23 edition of Modern C
#69Earlier quoted context omitted.
Namespaces is not object orientation, is it? Am I missing something? You can place functions (methods) inside of structs in C23, can't you?
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.
Re: The C23 edition of Modern C
#70Earlier quoted context omitted.
RAII
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 exp…
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.