C11 revision
Table of Contents
1 Overview
C11 is the informal name for ISO/IEC 9899:2011, the current standard for the C language that was ratified by ISO in December 2011.
It standardizes many features for safer programming, such as removal of gets() function.
Additionally, C11 adds concurrency support, type-generic expressions, alignment-related facilities, static assertion, unicode support, floating-point characteristic macros, no-return functions, anonymous structures and unions, and various bound-checking and reentrancy functions.
The following examples demonstrating C11 features can be compiled with options such as
clang -std=c11 ex.c
2 Multiple threading
C11 standardized multi-threading support.
It introduces new headers threads.h and stdatomic.h, supporting multiple threads of execution:
- threads creation and management
- mutexes
- conditional variables
- atomic objects
- thread specific storage
#include <stdio.h> #include <threads.h> #define NUM_THRD 5 int th_data[NUM_THRD]; int th_func(void *data) { printf("hi from thread %d\n", *(int *)data); thrd_sleep(&(struct timespec){ .tv_sec = 2 }, NULL); printf("bye thread %d\n", *(int *)data); return 0; } int main(void) { thrd_t t[NUM_THRD]; for (int i = 0; i < NUM_THRD; ++i) { th_data[i] = i; thrd_create(t + i, th_func, th_data + i); printf("%d-th thread created\n", i); } for (int i = 0; i < NUM_THRD; ++i) { thrd_join(t[i], NULL); } return 0; }
generates output similar to the following:
0-th thread created hi from thread 0 1-th thread created 2-th thread created hi from thread 2 hi from thread 1 3-th thread created 4-th thread created hi from thread 3 hi from thread 4 bye thread 0 bye thread 3 bye thread 1 bye thread 2 bye thread 4
3 Generic selection
Generic selection is a type-generic expressions using the _Generic keyword.
It allows to define type-generic macros or functions similar to the idea of overloading in C++.
The following macro typename(x) gives a string depending on the type name of x:
#include <stdio.h> #define typename(x) _Generic((x), \ int: "int", \ char: "char", \ double: "double", \ default: "other") int main(void) { printf("9 %s\n", typename(9)); printf("3.6 is %s\n", typename(3.6)); return 0; }
4 Alignment facilities
C11 introduces facilities to manually control memory alignment.
_Alignas keyword specifies a custom alignment for a variable or user-defined type and _Alignof reports the alignment of its operand.
The macros alignas and alignof are defined directly mapped to _Alignas and _Alignof, which match keywords used in C++.
For the following example
#include <stdio.h> #include <stdalign.h> typedef struct { char c; char data[16]; } s0; typedef struct { char c; alignas(16) char data[16]; } s1; int main(void) { printf("sizeof(s0): %zu, alignof(s0): %zu\n", sizeof(s0), alignof(s0)); printf("sizeof(s1): %zu, alignof(s1): %zu\n", sizeof(s1), alignof(s1)); return 0; }
The output will be
sizeof(s0): 17, alignof(s0): 1 sizeof(s1): 32, alignof(s1): 16
Every object in s1 is aligned to 16. So, sizeof(s0) = 32 bytes = 1 byte char + 15 bytes padding + 16 bytes data.
5 Static assertions
With macro static_assert, an expression can be evaluated at translation phase, when its type is known. So, compared to #if and #error preprocessor directives, it can detect errors that are not possible to detect during preprocessing phase.
In effect if the expression is evaluated equal to zero, a compile-time error occurs. Otherwise, if is not equal to zero, no code is emitted.
#include <assert.h> int main(void) { static_assert(2 + 2 == 4, "require to have 2 + 2 = 4"); //this produces a compile time error static_assert(sizeof(int) < sizeof(char), "require to have int size < char size"); return 0; }
6 Anonymous structs and unions
An anonymous struct or union has no name - neither tag name nor typedef name. It is useful for nesting aggregates.
A typical usage is to provide an alternative view to data.
#include <stdio.h> typedef union { struct { int width; int height; }; struct { int x; int y; }; } vec_t; int main(void) { vec_t point; point.x = 6; point.y = 9; printf("point.x = %d, point.y = %d\n", point.x, point.y); vec_t *rectangle = &point; printf("rectangle->width = %d, rectangle->height = %d\n", rectangle->width, rectangle->height); return 0; }
In the example, variable point represents a point on a coordinate system. Variable rectangle represents the rectangular area within point and origin, being the right-top and the left-bottom corner separately.
With C99, we have to name the structures, and the access to values of x and y will be instead something like point.s_data.x, that is verbose and less readable.
7 Other features
7.1 quick_exit() function
exit() ensures that stream buffers are flushed, closed, etc. However, quick_exit() only does minimal cleanup and exits a program quickly.
#include <stdlib.h> #include <stdio.h> void fquick(void) { puts("quick exit"); } void fnormal(void) { puts("normal termination"); } int main(void) { at_quick_exit(fquick); atexit(fnormal); quick_exit(EXIT_SUCCESS); puts("end of main"); return 0; }
The example outputs "quick exit" only.
7.2 _Noreturn function specifier
It declares a function does not return. _Noreturn specifier is to suppress compiler warnings on a non returning function, and enable certain optimizations that are only allowed on non returning functions.
7.3 Bounds-checking functions
It defines bound checking version of functions having _s suffix appended to the original function names, strcat_s() etc.
7.4 Unicode support
Prefixes u and U introduce UTF-16 and UTF-32 characters and strings.
UTF-8 encoding strings can be enforced with prefix u8.
#include <uchar.h> char u8str[] = u8"UTF-8 string π"; char u8chr = u8'π'; char16_t u16str[] = u"UTF-16 string π"; char16_t u16char = u'π'; char32_t u32str[] = U"UTF-32 string π"; char32_t u32char = U'π';
7.5 complex types
#include <stdio.h> #include <complex.h> int main(void) { double complex z = CMPLX(6.0, 9.0); printf("Value: %f-%fi\n", creal(z), cimag(z)); return 0; }
8 C17 / C18
Since it was prepared in 2017 and published in 2018, C17 is also referred to as C18.
C17 addressed defects in C11 without introducing new language features.
9 C2x
C2x is an informal name. It is expected to be voted on in 2023, and will be C23.
Refer to wikipedia/C2x for more information.
10 References
- ISO/IEC JTC1/SC22/WG14 - C, www.open-std.org
- C99 ISO/IEC 9899:1999, Committee Draft N1256 (PDF)
- C11 ISO/IEC 9899:2011, Committee Draft N1570 (PDF)
- C17 ISO/IEC 9899:2018, Committee Draft N2310 (PDF)
- C2x Draft N3054 (Sep 2022) (PDF)
- Revised C23 Schedule - N2759 (PDF)
- ISO/IEC 60559
- #C on Freenode and Libera, The Standard, www.iso-9899.info
- cppreference, en.cppreference.com
- wikipedia, www.wikipedia.org
- Carnegie Mellon University, SEI CERT C Coding Standard, wiki.sei.cmu.edu
- Danny Kalev, C11: A New C Standard Aiming at Safer Programming
- stackoverflow, stackoverflow.com
- Multi-Threading support in c11
- When are anonymous structs and unions useful in C11?
- What is the point of noreturn?
- C11 Unicode Support
- C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?
- C11 Annex K: "objects that overlap"
- Difference between exit and quick_exit
- Microsoft Learn
- Robert Gamble, C11 - Generic Selections
- Clang Compiler User’s Manual
- Jens Gustedt, Unicode operators for C
- H. Boehm, Threads and memory model for C++
Created: 2022-12-19 Mon 13:46
No comments:
Post a Comment