C23: A Slightly Better C


Skip to content

One of the established and most popular programming languages is the C programming language. It is relatively easy to learn, and highly practical.

Maybe surprisingly, the C programming language keeps evolving, slowly and carefully. If you have GCC 13 or LLVM (Clang) 16, you already have a compiler with some of the features from the latest standard (C23).

// Only include stdio.h if it exists
#if __has_include (<stdio.h>)
  #include <stdio.h>
#endif

#include <stdlib.h>

[[deprecated]]
void f() {}

[[nodiscard]]
int g(int x) {
  return x + 1;
}

int main() {
  f(); // compile-time warning: 'f' is deprecated
  g(1); // compile-time warning
  auto x = 0b1111;
  typeof(x) y = 1'000'000; // type of y is the same as x
  printf("%dn", x); // prints 15
  printf("%dn", y); // prints 1000000
  constexpr int N = 10;
  // compile-time asserts using static_assert
  static_assert (N == 10, "N must be 10");
  bool a[N]; // array of N booleans
  for (int i = 0; i < N; ++i) {
    a[i] = true;
  }
  printf("%dn", a[0]); // prints 1
}

  1. The first part of the code contains some preprocessor directives, which are instructions for the compiler to process the source code before compiling it. The #if directive checks a condition at compile time and includes the following code only if the condition is true. The __has_include macro is a feature of C++17 adopted by C23 that checks if a header file exists and can be included. In this instance, it is not useful because we know that stdio.h is present, but in other instances, this can prove useful to determine what headers are available.
  2. The next part of the code defines two functions with attributes, which are annotations that provide additional information to the compiler about the behavior or usage of a function, variable, type, etc.
    • The [[deprecated]] attribute is a feature of C++14 adopted by C23 that marks a function as obsolete and discourages its use. The compiler will issue a warning if the function is called or referenced.
    • The [[nodiscard]] attribute is a feature of C++17 adopted by C23 that indicates that the return value of a function should not be ignored or discarded. The compiler will issue a warning if the function is called from a discarded-value expression.

    In this case, the function f is deprecated and does nothing, while the function g returns the input value plus one and should not be ignored. The first two lines of the main function call the functions f and g and trigger the warnings.

  3. The third line of the main function declares a variable x with the auto keyword, which is a feature of C++11 that lets the compiler deduce the type of the variable from its initializer. In this case, the initializer is a binary literal, which is a feature of C++14 and adopted by C23 that allows writing integer constants in binary notation using the prefix 0b. The value of x is 0b1111, which is equivalent to 15 in decimal.
  4. The fourth line declares another variable y with the typeof operator that returns the type of an expression. In this case, the expression is x, so the type of y is the same as the type of x. The initializer of y is a digit separator, which is a feature of C++14 adopted by C23 that allows inserting single quotes between digits in numeric literals to improve readability. The value of y is 1’000’000, which is equivalent to 1000000 in decimal.
  5. The seventh line declares a constant variable N with the constexpr keyword, which is a feature of C++11 adopted by C23 that indicates that the value of the variable can be evaluated at compile time. The value of N is 10. Previously, one would often use a macro to define a compile-time constant (e.g., #define N 10).
  6. The eighth line uses the static_assert keyword, which is a feature of C++11 adopted by C23 that performs a compile-time assertion check. The keyword takes a boolean expression and an optional string message as arguments. If the expression is false, the compiler will emit an error and stop the compilation, displaying the message. If the expression is true, the compiler will do nothing. In this case, the expression is N == 10, which is true, so the compilation continues.
  7. The ninth line declares an array of N booleans named a. An array is a collection of elements of the same type that are stored in contiguous memory locations. The size of the array must be a constant expression, which is why N is declared with constexpr. We also use the keywords true and false which become standard in C23.

There are many more features in C23, but it will take some time for compilers and system librairies to catch up.

My thoughts so far:

  • The introduction of constexpr in C will probably help reduce the dependency on macros, which is a good idea generally. Macros work well in C, but when a bug is introduced, it can be difficult get meaningful error messages. It does not happen too often, but in large code bases, it can be a problem.
  • I personally rarely use auto and typeof in other languages, so I don’t expect to use them very much in C. In some specific cases, it can greatly simply one’s code, however. It is likely going to help reduce the reliance on macros.
  • The idea behind static_assert is great. You run a check that has no impact on the performance of the software, and may even help it. It is cheap and it can catch nasty bugs. It is not new to C, but adopting the C++ syntax is a good idea.
  • The __has_include feature can simplify supporting diverse compilers. It is good idea.

Published by

Read More
Gaylene Pecora

Latest

Too Little, Too Late? Sony Music Fires Off Blanket Warning Against the AI Mining of Its Catalog

Too little, too late? Sony Music has fired off a blanket warning against the unauthorized training of AI systems on its song catalog and other IP. The overarching Sony Music Group today made that clear-cut announcement on behalf of Sony Music Entertainment (SME) as well as its various subsidiaries and Sony Music Publishing (SMP). Spanning

Pandora Hits Back at MLC Lawsuit Over Streaming Royalties: ‘Legally Incoherent’

Music In a strongly-worded response, Pandora says the royalties...

Newsletter

Don't miss

Too Little, Too Late? Sony Music Fires Off Blanket Warning Against the AI Mining of Its Catalog

Too little, too late? Sony Music has fired off a blanket warning against the unauthorized training of AI systems on its song catalog and other IP. The overarching Sony Music Group today made that clear-cut announcement on behalf of Sony Music Entertainment (SME) as well as its various subsidiaries and Sony Music Publishing (SMP). Spanning

Pandora Hits Back at MLC Lawsuit Over Streaming Royalties: ‘Legally Incoherent’

Music In a strongly-worded response, Pandora says the royalties...

News24 Business | For R350 a month, residents of informal settlements can use a waterless toilet

Qaqamba Matundu Share your Subscriber Article You have 5 articles to share every month. Send this story to a friend! Loading, please wait... Subscribers can listen to this article A waterless toilet provides clean and safe sanitation for informal residents (Ntando Mbhele/ Supplied). A waterless flushing toilet, to help communities that lack water and sanitation

Want to succeed in business? Find a problem to solve | Anthony Tan and Amane Dannouni

Update requirements Looking for ted.com? v95+ v58+ v13+ v96+ v82+ Looks like your browser is out of date For questions contact us at support@ted.com

News24 Business | Garth Theunissen | SENS needs fixing, but the JSE disagrees

Subscribers can listen to this article The JSE building in Sandton. (Fivepointsix/Getty) While the JSE has made efforts to simplify its listing requirements, little evidence of this can be seen in many an indecipherable regulatory announcement. Given the plethora of scandals involving JSE-listed companies in recent years, perhaps it's time to consider some plainer language