New C23 Language Features

While other programming languages seem to improve and update in great leaps, C moves at a glacial pace. The C23 upgrade offers a few new and exciting features, but nothing I would call impressive or awesome.

For example, one of the new decimal floating-point math function is decodedecdN(). I have no idea what it does and neither does the Internet. Decimal representation of floating point values reduces rounding errors, yet no other specifics are available on how this or the other dN functions behave.

The C23 library supports UTF-8 characters with the addition of the char8_t data type and two new functions: mbrtoc8() and c8rtomb(). These functions convert between the multibyte character format and UTF-8. They’re prototyped in the uchar.h header file.

The memset_explict() function works like memset(), but is safe for sensitive information. This function supersedes the non-standard memset_s() function for securely writing to a buffer.

The following POSIX functions are now part of the standard C library: memccpy(), strdup(), strndup(), gmtime_r(), and localtime_r().

The C23 standard introduces the timespec_getres() function, defined in the time.h header file. This function uses a timespec structure, which holds time values including nanoseconds.

Other new features include header files stdbit.h and stdckdint.h, neither of which I have access to so I can only guess what they do.

Also added a slew of testing macros for various versions, such as __STDC_VERSION_MATH_H__ which I can guess returns the version number for the math library. Again, official documentation is scant.

Four new preprocessor directives are available: #elifdef and #elifndef work to create if-else decision trees for defined constants. Most likely, these directives work with #ifdef and #ifndef to truly weed out definitions.

The #error and #warning preprocessor directives throw compiler error and warnings, respectively. The #error directive is followed by a diagnostic message that’s output, then the build stops. The #warning directive is also followed by a diagnostic message to output, though this directive doesn’t halt the build.

Two new pragmas are available to set rounding direction: FENV_ROUND and FENV_DEC_ROUND. I’ve found no details are available on what these pragmas do.

To me, most of these features seem esoteric, though I can see how they’re necessary. C must maintain consistency, so features many programmers may desire will never make the cut. Further, these new features are completely implemented on any compiler I can find. I figure they’ll slowly evolve over the years, just like the rest of C.

For next week’s Lesson, I conclude my survey by revealing which C features have been removed and which are now deprecated with the C23 standard.

5 thoughts on “New C23 Language Features

  1. As I see it, thereʼs really only one reason the new standard adds char8_t—with Cʼs char type itʼs compiler-dependent whether one gets a signed or an unsigned 8-bit integer type. On the other hand, char8_t is always unsigned, fixes this.

    A short description of the contents of the new <stdbit.h> header file can be found on Wikipedia and in section §7.18 of the most recent publicly available draft. In short, this header provides standardized bit utility functions so that one doesnʼt have to resort to bittwiddling hacks or vendor-specific functions. For example, to calculate the number of bits set in a value (the “population count”), up until now one would have to call __popcnt() on Windows (MSVC), __builtin__popcount() (for GCC) or resort to bitwise hacks… now one can just call stdc_count_ones_uX() and be done with it.

    The new <stdckdint.h> header file is also quite an interesting addition: code that reliably checks for potential integer overflow is not always easy to write… such checks were often quite error-prone in the past. To address this, the standard introduces 3 new functions,

    bool ckd_add(type1 *result, type2 a, type3 b);
    bool ckd_sub(type1 *result, type2 a, type3 b);
    bool ckd_mul(type1 *result, type2 a, type3 b);

    that can can be used to safely perform arithmetic operations (the functions themselves signaling if overflow occurred). JeanHeyd “ThePhD” Meneide discusses these functions on his blog “The Pasture” (under the heading “N2683 – Towards Integer Safety”).

    A description of FENV_ROUND and FENV_DEC_ROUND can be found in sections §7.6.2 and §7.6.3, respectively, of the most recent publicly available draft. To be honest, I havenʼt had the chance to try this out for myself, but with this compiler pragma it should be possible to request floating-point “rounding mode”s (FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD) by placing them after this pragma within a translation unit… it then being the compilerʼs job to make sure that all calls to some “special” floating-point functions (i.e. ones that respect this pragmaʼs setting) act as if the corresponding rounding mode had been set by calling fesetround(); (the standard contains a full list of floating-point functions this pragma pertains to).

    While FENV_ROUND sets such a “constant rounding direction” (as the standard calls it) for binary floating-point numbers, FENV_DEC_ROUND does the same thing for _Decimal32, _Decimal64, and _Decimal128, the new decimal floating-point types (as per IEEE 754-2008).

    Full details for all of the above can be found in “n3096.pdf”, the most recent publicly available draft PDF.

  2. One other thing: although I mentioned the standard several times in my post, Iʼll be the first to admit that “standardese” isnʼt easy to read… not by a long shot. Luckily, it looks like the first books specifically targeting C23 will, in the not-so-distant future, hit the market. For example, the third edition Jens Gustedts “Modern C” is already available as a MEAP. (Not affiliated in any way.)

    Are there already plans for a third edition of “C For Dummies” as well? Are you allowed to divulge any information regarding this?

  3. I was asked to review Gustedts’ book (and have the PDF on my desktop). Alas, I didn’t have time to review it. It’s truly a meaty book, well worth the read. I was busy updating one of my online C courses at the time and couldn’t meet Manning’s deadline.

    The C++ For Dummies book far outsells my C For Dummies. It gets updated more frequently. The publisher is more interested in sales than keeping current with the language. My book needs an update, if anything, because I use Code::Blocks and it’s just clunky. I need to move to Visual Studio, which is consistent across all platforms.

  4. Pity, really, that “C” has somewhat been relegated to embedded systems, modern C++ and (especially) Rust being all the craze—that of course driving book sales.

    Although I personally have always had a soft spot for Codelite (instead of Code::Blocks), I agree: if you ever get to do an update to your book, Visual Studio Code will most likely be the obvious choice.

    Thank you for this detailed answer!

Leave a Reply