Skip to main content

Command Palette

Search for a command to run...

Notable & useful improvements to the C programming language from C99 to C23

Updated
3 min read
Notable & useful improvements to the C programming language from C99 to C23

The evolution & improvement of the C language from C99 to C23 has been a big one, notably from the removal of K&R style headers(which was the 1st introduction to the C language for me) to the introduction of modern keywords.

To use the modern features you will first have to enable C23 support in your IDE or explicitly use the flag with compiler - $gcc -std=c23 main.c -o main

C23:

  1. Adds the auto keyword for type inference,similar to the commonly used C++ auto keyword.

  2. Attribute additions:

    • _Static_assert(without a mandatory message).

    • [[nodiscard]] - tells compiler to not ignore the return value

   // [[nodiscard]] - tells compiler to not ignore the return value
   // Addition of the string is optional,write the warning you want to be thrown

   [[nodiscard("Always check for the return value(s)")]]
   int process_data(void) {
       return -1;
   }
   
int main(){

		process_data();
        return 0;
}
  1. [[maybe_unused]] - Used to suppress compiler warnings for entities that are intentionally declared but might not be used.
#include <assert.h>

// Most compilers would warn you about an un-used variable
void process_data(int val) {
    int result = 10;
    assert(result > 0);
}

// Suppress warning if 'result' is only used inside the assert()
// Without [[maybe_unused]], the compiler would warn about an unused variable.
void process_data1(int val) {
    [[maybe_unused]] int result = 10;
    assert(result > 0);
}

int main(){
	
	}
  1. Addition of memset_explicit - designed to erase sensitive data(e.g cryptographic keys,passwords) from memory. Unlike memset, it is guaranteed to never be optimized away by the compiler. The difference between memset & memset_explicit is that memset_explicit forces the write to memory ensuring data is overwritten whereas memset may optimize data away if it determines that the memory is not read again,this leaves sensitive data in memory.

  2. Expanded <tgmath.h> & added support for decimal floating-point types - (_Decimal32 d32 = 1.0df; _Decimal64 d64 = 2.5dd; _Decimal128)

  3. The famous keyword NULL is now superseded by nullptr.

  4. _BigInt(n) - Allows for integers of exact bit-widths(up to 64 or 128 bits),provides more flexibility than the standard int,long & long long.

  5. Improvements on atomic operations & thread-local storage behavior.

  6. Bit manipulation improvements:

    • stdc_count_ones(x) - Returns the number of set bits.

    • stdc_bit_ceil(x) - Rounds up to the nearest power of 2.

  7. <stdckdint.h> - The new checked arithmetic macros returns a boolean indicating if an overflow occurred while simultaneously performing the operation.

A few more new library functions & its associated header(C11 - C23)

Header Standard Notable Functions / Macros Purpose
<stdbit.h> C23 stdc_count_ones, stdc_bit_ceil, stdc_has_single_bit Type-generic macros for bit manipulation (counting bits, finding powers of 2).
<threads.h> C11 thrd_create, mtx_lock, cnd_wait Native, cross-platform support for multi-threading and mutexes.
<stdatomic.h> C11 atomic_store, atomic_fetch_add Safe concurrent access to variables without manual locking.
<string.h> C23 memset_explicit, strdup, strndup Secure memory wiping and standardizing common POSIX string cloning.
<stdlib.h> C23 free_sized, free_aligned_sized, aligned_alloc Enhanced memory management for performance and alignment control.
<math.h> C23 exp10, cospi, sinpi, compound New transcendental and financial math functions based on IEEE 754-2019.
<time.h> C23 timegm Converts a struct tm (UTC) directly to time_t (formerly a non-standard extension).
<stdckdint.h> C23 ckd_add, ckd_sub, ckd_mul Checked Integer Arithmetic: Macros that detect integer overflow safely.