| # C23 language changes |
| |
| ## Breaking changes |
| |
| ### `void foo()` now means `void foo(void)` |
| In C17 and earlier, `void foo()` means "I haven't yet told you how many |
| arguments this function has". In C23, it's equivalent to C++ and means "this |
| function has no arguments". This may surface as a function pointer type |
| mismatch, because previously `()` matched functions taking any arguments, |
| whereas in C23 it only matches functions taking no arguments. |
| |
| Fix: in cases where your function does have arguments, declare them. |
| |
| ### Undeclared identifiers are now errors |
| In C17 and earlier, calling `foo(123)` without a declaration for `foo()` |
| produced a warning. In C23 this is an error instead. One common special case of |
| this is code that's explicitly ignoring such warnings to call functions that are |
| GNU extensions; such code should be fixed to ensure that `_GNU_SOURCE` is |
| defined before any header is included instead (often by adding `-D_GNU_SOURCE` |
| to the cflags in the build file). |
| |
| Fix: add the missing forward declaration or `#include` (or `-D_GNU_SOURCE`). |
| |
| ### `bool`/`true`/`false` are now keywords |
| In C17 and earlier, only code that included `<stdbool.h>` would have standard |
| definitions for these (typically macros for `_Bool`/`1`/`0`). In C23 these are |
| keywords and should no longer be defined in your code. |
| |
| Fix: delete any definitions of `bool`/`true`/`false` if you only need to build |
| as C23, or switch to `#include <stdbool.h>` for compatibility back to C99. |
| |
| ### `false` is no longer `0` |
| In C17 and earlier, it was common for true and false to be defined as 1 and 0 |
| (either by `<stdbool.h>` or by user-provided `#define`/`enum`). This meant that |
| `false` (as 0) could be implicitly converted to `NULL`. In C23, a function that |
| returns (or takes) a pointer can no longer return `false` (or be passed |
| `false`). |
| |
| Fix: return/pass `NULL` (or `nullptr` for C23-only code) instead of `false` |
| in pointer contexts. |
| |
| ### `unreachable()` is now a predefined function-like macro in `<stddef.h>` |
| In C17 and earlier, `unreachable()` was available for your own macros/functions. |
| In C23 there's a standard definition. |
| |
| Fix: delete your `unreachable()` if it was just equivalent to |
| `__builtin_unreachable()` or rename it if it had different behavior. |
| |
| ### K&R prototypes are no longer valid |
| In C17 and earlier, K&R function prototypes were deprecated but still allowed. |
| In C23 K&R prototypes are no longer allowed. |
| |
| Fix: rewrite any K&R prototypes as ANSI/ISO prototypes. |
| |
| |
| ## Non-breaking changes |
| |
| ### Unused function parameters can now be anonymous |
| In C17 and earlier you'd have to use `__attribute__((unused))` on an unused |
| function parameter. In C23 you can just omit the parameter name instead, |
| like `void* pthread_callback_fn(void*) {` (as in C++). |
| |
| ### New standard attributes |
| C23 adds `[[deprecated("reason")]]`, `[[fallthrough]]`, `[[nodiscard]]` (the |
| equivalent of the clang attribute `warn_unused_result`), |
| `[[maybe_unused]]` (the equivalent of the clang attribute `unused`), |
| and `[[noreturn]]` (equivalent to C11 `_Noreturn`). |
| Most of these have been available before via `__attribute__` or other syntax, |
| but are now standard. |
| |
| ### `#embed` |
| You can now include binary data directly into an array or string: https://en.cppreference.com/w/c/preprocessor/embed |
| |
| ### `void foo(...)` is now allowed |
| In C17 and earlier, a varargs function needed a non-varargs argument. |
| In C23 this is allowed (as in C++). |
| |
| ### `enum` base types |
| You can now say `enum E : long { ... }` to explicitly choose the base type of |
| your enum (as in C++, and already supported by clang as an extension). |
| |
| ### `nullptr` constant |
| There is now a `nullptr` constant (as in C++), |
| and a corresponding `nullptr_t` type for that constant. |
| |
| ### `constexpr` |
| There is now a limited form of `constexpr` for defining `const` variables |
| (similar to, but much more limited than C++ constexpr). |
| |
| |
| ## Library changes |
| |
| Library changes are not covered here because bionic does not make library |
| functionality available based on target C version, since the target API level |
| distinctions are confusing enough already. |
| |
| See [status.md](status.md) for what functionality went into which API level. |