diff --git a/content/atomic-floating-min-max.md b/content/atomic-floating-min-max.md index 6b300c9..78b4562 100644 --- a/content/atomic-floating-min-max.md +++ b/content/atomic-floating-min-max.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The `fetch_max`, `fetch_min`, `fetch_fmaximum`, `fetch_fminimum`, `fetch_fmaximum_num`, and `fetch_fminimum_num` diff --git a/content/auto.md b/content/auto.md index 518cee3..1f9bb1a 100644 --- a/content/auto.md +++ b/content/auto.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The `auto` keyword specifies that a variable's type is deduced from its initializer. diff --git a/content/bit-cast.md b/content/bit-cast.md index 8b4006a..255f9ed 100644 --- a/content/bit-cast.md +++ b/content/bit-cast.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::bit_cast()` reinterprets the object representation of one type as another type. diff --git a/content/c-alignas-alignof.md b/content/c-alignas-alignof.md index 0476471..2e88df3 100644 --- a/content/c-alignas-alignof.md +++ b/content/c-alignas-alignof.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Alignas(N)` specifies the alignment requirement for a variable or type. `_Alignof(type)` diff --git a/content/c-anonymous-struct-union.md b/content/c-anonymous-struct-union.md index 09431e6..c1f288b 100644 --- a/content/c-anonymous-struct-union.md +++ b/content/c-anonymous-struct-union.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does Anonymous structures and unions are members without a declared name. Their members are accessed diff --git a/content/c-array-parameter-qualifiers.md b/content/c-array-parameter-qualifiers.md new file mode 100644 index 0000000..1a92533 --- /dev/null +++ b/content/c-array-parameter-qualifiers.md @@ -0,0 +1,38 @@ +## What It Does + +A function parameter written with array syntax is adjusted to a pointer. Inside the square brackets +of the outermost array derivation, C99 permits the keyword `static` followed by a size, and the +qualifiers `const`, `volatile`, and `restrict`. Writing `double a[static 10]` tells the compiler the +argument points to the first element of an array holding at least ten elements. A qualifier in the +brackets applies to the adjusted pointer, so `double a[const]` means `double *const a`, and +`restrict` marks it as a restricted pointer. + +## Why It Matters + +Because an array parameter decays to a plain pointer, the declaration loses any record of how many +elements the caller must supply and any qualification on the pointer itself. Without that +information a translator cannot assume a minimum extent, so it cannot prefetch or vectorize loads of +the elements at function entry. Placing `static N` in the brackets records that at least N elements +are accessible, that the pointer is non-null, and that it points to an object of the appropriate +effective type. The qualifiers let the adjusted pointer be `const`, `volatile`, or `restrict`, and +`restrict` in particular tells the optimizer the named arrays do not overlap, enabling loop +unrolling and reordering of loads and stores. The restriction to the outermost derivation reflects +that only there does the syntax describe the pointer the parameter becomes. + +## Example + +```c +#include + +double average(const double a[static const 3]) +{ + return (a[0] + a[1] + a[2]) / 3.0; +} + +int main(void) +{ + double values[3] = {4.0, 6.0, 8.0}; + printf("average = %.2f\n", average(values)); + return 0; +} +``` diff --git a/content/c-atomic.md b/content/c-atomic.md index 2f8514c..30d3848 100644 --- a/content/c-atomic.md +++ b/content/c-atomic.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Atomic` qualifies a type to enable atomic operations without data races. The `` diff --git a/content/c-attributes.md b/content/c-attributes.md index c1fc96b..a55f69f 100644 --- a/content/c-attributes.md +++ b/content/c-attributes.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does C23 introduces standard attributes using the `[[attribute]]` syntax. Standard attributes diff --git a/content/c-auto.md b/content/c-auto.md index 6859ef4..fe6bf6c 100644 --- a/content/c-auto.md +++ b/content/c-auto.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `auto` in C23 enables type inference for object definitions with initializers. The compiler diff --git a/content/c-binary-literals.md b/content/c-binary-literals.md index a8747cb..90a92a7 100644 --- a/content/c-binary-literals.md +++ b/content/c-binary-literals.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does Integer constants can be written in binary using the `0b` or `0B` prefix followed by binary diff --git a/content/c-bitint.md b/content/c-bitint.md index eda78b4..adda697 100644 --- a/content/c-bitint.md +++ b/content/c-bitint.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `_BitInt(N)` defines an integer type with exactly N bits of precision. Both signed and diff --git a/content/c-bool-true-false.md b/content/c-bool-true-false.md index f8cf281..b12948d 100644 --- a/content/c-bool-true-false.md +++ b/content/c-bool-true-false.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `true`, `false`, and `bool` are predefined keywords in C23. `bool` is a standard type, diff --git a/content/c-cmplx.md b/content/c-cmplx.md new file mode 100644 index 0000000..e155f17 --- /dev/null +++ b/content/c-cmplx.md @@ -0,0 +1,34 @@ +## What It Does + +`CMPLX(x, y)` is a function-like macro in `` that builds a `double complex` value whose +real part is `x` and whose imaginary part is `y`, each converted to `double`. `CMPLXF` and `CMPLXL` +do the same for `float complex` and `long double complex`. Each may appear in a static initializer +whenever both arguments could themselves initialize the corresponding real type statically. + +## Why It Matters + +There was no portable expression that constructs an arbitrary complex value component by component. +The idiomatic `x + y*I` breaks when `I` has complex type, which is the usual case because imaginary +types are optional. If `y` is an infinity or a NaN, `y*I` yields a complex value whose real part is +NaN rather than zero, and adding `x` then contaminates the real part, so the result is not `x + iy`. +The macros behave as if `I` were purely imaginary, routing each argument into exactly one component. +That keeps infinities and NaNs confined to the part they belong to, and makes construction usable in +static initializers, which the earlier form could not reliably support. + +## Example + +```c +#include +#include +#include + +int main(void) +{ + double complex a = CMPLX(3.0, INFINITY); + double complex b = 3.0 + INFINITY * I; + + printf("CMPLX: re=%g im=%g\n", creal(a), cimag(a)); + printf("naive: re=%g im=%g\n", creal(b), cimag(b)); + return 0; +} +``` diff --git a/content/c-compound-literals.md b/content/c-compound-literals.md index d340fd5..21b83c1 100644 --- a/content/c-compound-literals.md +++ b/content/c-compound-literals.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Compound literals create unnamed objects of a specified type using the syntax diff --git a/content/c-constexpr.md b/content/c-constexpr.md index 8184643..21bf235 100644 --- a/content/c-constexpr.md +++ b/content/c-constexpr.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `constexpr` specifies that an object's value is a constant expression and must be computable diff --git a/content/c-designated-init.md b/content/c-designated-init.md index 5b5cc93..60a16cf 100644 --- a/content/c-designated-init.md +++ b/content/c-designated-init.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Designated initializers specify which member or element to initialize using `.member` for diff --git a/content/c-digit-separators.md b/content/c-digit-separators.md index 5e56c04..148b4fd 100644 --- a/content/c-digit-separators.md +++ b/content/c-digit-separators.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does Single quote characters (`'`) can appear within integer and floating-point constants to diff --git a/content/c-elifdef.md b/content/c-elifdef.md index 980b326..d5992ec 100644 --- a/content/c-elifdef.md +++ b/content/c-elifdef.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `#elifdef` and `#elifndef` are preprocessor directives that combine `#elif` with `#ifdef` diff --git a/content/c-embed.md b/content/c-embed.md index 703f673..289b4e7 100644 --- a/content/c-embed.md +++ b/content/c-embed.md @@ -1,7 +1,3 @@ ---- -show_only: true ---- - ## What It Does `#embed` is a preprocessor directive that includes the contents of a binary file as a diff --git a/content/c-empty-init.md b/content/c-empty-init.md index 082f094..0489da1 100644 --- a/content/c-empty-init.md +++ b/content/c-empty-init.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does Empty initializers `{}` zero-initialize an object. For structures and arrays, all members diff --git a/content/c-enum-trailing-comma.md b/content/c-enum-trailing-comma.md new file mode 100644 index 0000000..af2739e --- /dev/null +++ b/content/c-enum-trailing-comma.md @@ -0,0 +1,32 @@ +## What It Does + +C99 permits a comma after the final constant in an enumerator list, so +`enum color { RED, GREEN, BLUE, };` is valid. The trailing comma is punctuation only. It introduces +no additional enumerator and leaves the enumeration's values unchanged. + +## Why It Matters + +With a trailing comma permitted, every enumerator line has the same form, including the last. +Adding, removing, or reordering entries then changes only the lines involved, and code that +generates an enumerator list need not special-case its final element. C already allowed a trailing +comma in initializer lists, so the same treatment for enumerators keeps the two consistent. + +## Example + +```c +#include + +enum color +{ + RED, + GREEN, + BLUE, +}; + +int main(void) +{ + enum color c = BLUE; + printf("BLUE = %d\n", c); + printf("count = %d\n", BLUE + 1); +} +``` diff --git a/content/c-fenv.md b/content/c-fenv.md new file mode 100644 index 0000000..ce48355 --- /dev/null +++ b/content/c-fenv.md @@ -0,0 +1,46 @@ +## What It Does + +`` gives a program execution-time access to the floating-point environment. That environment +holds the status flags that record exceptions (invalid, division-by-zero, overflow, underflow, +inexact) and the control modes, chiefly the rounding direction. `feclearexcept`, `fetestexcept`, +`feraiseexcept`, and `fegetexceptflag`/`fesetexceptflag` inspect and manipulate the exception flags; +`fegetround`/`fesetround` read and change the rounding direction among `FE_TONEAREST`, +`FE_TOWARDZERO`, `FE_UPWARD`, and `FE_DOWNWARD`; `fegetenv`, `fesetenv`, `feholdexcept`, and +`feupdateenv` save, restore, and combine the whole environment. `#pragma STDC FENV_ACCESS ON` tells +the translator that code may test flags or depend on non-default modes. + +## Why It Matters + +IEC 60559 arithmetic defines sticky exception flags and a dynamic rounding direction that hardware +keeps in control registers, but the language had no portable way to reach them. The rounding mode is +inherently dynamic, since a function must inherit its caller's mode, so a static translator-declared +model was rejected. Dynamic modes conflict with optimization, because the translator otherwise +cannot know which rounding is active or whether flags are read. The `FENV_ACCESS` pragma marks the +regions where the environment must be respected and leaves the compiler free elsewhere. `fexcept_t` +is deliberately opaque so implementations can attach extra per-exception information; its values +come only from `fegetexceptflag`. + +## Example + +```c +#include +#include +#include + +#pragma STDC FENV_ACCESS ON + +int main(void) +{ + feclearexcept(FE_ALL_EXCEPT); + volatile double z = 0.0; + volatile double q = 1.0 / z; + (void)q; + if (fetestexcept(FE_DIVBYZERO)) + printf("divide-by-zero flag raised\n"); + + fesetround(FE_DOWNWARD); + printf("rint(2.5) downward = %.1f\n", rint(2.5)); + fesetround(FE_UPWARD); + printf("rint(2.5) upward = %.1f\n", rint(2.5)); +} +``` diff --git a/content/c-fixed-enum.md b/content/c-fixed-enum.md index 2c2c173..33596f1 100644 --- a/content/c-fixed-enum.md +++ b/content/c-fixed-enum.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does Enumerations can specify a fixed underlying type using the syntax `enum Name : Type { ... }`. diff --git a/content/c-flexible-array.md b/content/c-flexible-array.md index bcd11ae..2493df7 100644 --- a/content/c-flexible-array.md +++ b/content/c-flexible-array.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does A flexible array member is an array declared with no size as the last member of a structure. diff --git a/content/c-fopen-exclusive.md b/content/c-fopen-exclusive.md new file mode 100644 index 0000000..3153cab --- /dev/null +++ b/content/c-fopen-exclusive.md @@ -0,0 +1,43 @@ +## What It Does + +Appending `x` as the final character of an `fopen()` (or `freopen()`) mode string requests exclusive +creation. The character is valid only with the write modes, giving `"wx"`, `"wbx"`, `"w+x"`, and +`"w+bx"`/`"wb+x"`. If the named file already exists, or cannot be created, the call fails and +returns `NULL`. Otherwise the file is created and opened with exclusive access, to the extent the +underlying system supports it. Read and append modes do not accept `x`. + +## Why It Matters + +Plain `"w"` truncates an existing file or creates a new one and never reports which happened, so +overwriting an unintended file goes unnoticed. Code that wanted a fresh file used to test for +existence first, then open for writing. Between those two steps another process on a shared system +can create or link the name, and the second open follows or clobbers it. Folding creation-if-absent +into one atomic step closes that race, mirroring POSIX `open()` with `O_CREAT | O_EXCL`. + +## Example + +```c +#include + +int main(void) +{ + const char *name = "cppstat_excl.tmp"; + + FILE *f = fopen(name, "wx"); + if (f) + { + fputs("first\n", f); + fclose(f); + printf("created\n"); + } + + FILE *g = fopen(name, "wx"); + if (g == NULL) + printf("refused (file exists)\n"); + else + fclose(g); + + remove(name); + return 0; +} +``` diff --git a/content/c-for-loop-declarations.md b/content/c-for-loop-declarations.md new file mode 100644 index 0000000..408384b --- /dev/null +++ b/content/c-for-loop-declarations.md @@ -0,0 +1,35 @@ +## What It Does + +C99 permits the first clause of a `for` statement to be a declaration rather than an expression. +Identifiers declared there are scoped to the loop alone, covering the controlling expression, the +update expression, and the body, and they cease to exist once the loop ends. A loop may contain one +such declaration, which can introduce several comma-separated variables, and those variables must +have automatic storage, so only `auto` or `register` are allowed, never `static`, `extern`, or +`typedef`. + +## Why It Matters + +A loop counter is usually set up at the top of the loop and never used afterward. Under C89 it had +to be declared at the start of the enclosing block, where it stayed in scope for the rest of that +block, inviting accidental reuse and name clashes with unrelated variables. Declaring the counter +inside the `for` statement confines it to a narrower scope covering only the loop, so it does not +modify any outer variable of the same name and is destroyed at loop end, which also gives the +compiler room to optimize. Restricting the clause to a single declaration of automatic-storage +objects keeps the syntax simple. + +## Example + +```c +#include + +int main(void) +{ + int i = 99; /* outer i, untouched by the loop */ + + for (int i = 0, j = 10; i < 3; i++, j--) + printf("i=%d j=%d\n", i, j); + + printf("outer i is still %d\n", i); + return 0; +} +``` diff --git a/content/c-fp-pragmas.md b/content/c-fp-pragmas.md new file mode 100644 index 0000000..fdad2f2 --- /dev/null +++ b/content/c-fp-pragmas.md @@ -0,0 +1,40 @@ +## What It Does + +C99 reserves the pragma namespace whose first preprocessing token is `STDC` for standard directives +and defines three pragmas that control how the translator handles floating-point code. +`#pragma STDC FP_CONTRACT` sets whether expressions may be contracted, for example into a fused +multiply-add that rounds once. `#pragma STDC FENV_ACCESS` sets whether the program may access the +floating-point environment, meaning rounding modes and exception flags. +`#pragma STDC CX_LIMITED_RANGE` sets whether the shorter complex multiply and divide formulas may be +used. Each takes an on-off-switch of `ON`, `OFF`, or `DEFAULT`. Each must appear at file scope or at +the start of a compound statement, before any statement or declaration, and its effect runs to the +end of that scope. + +## Why It Matters + +These settings are directions to the compiler about code generation, not runtime operations, so they +must live in the translation unit and be known at compile time. The lexical, scoped placement lets +the compiler bound exactly which regions of code each mode governs. A reserved `STDC` namespace +keeps standard directives from colliding with the vendor-specific pragmas compilers already defined. +Under `FENV_ACCESS OFF` the implementation need not maintain the exception flags, so aggressive +optimization stays available where the program does not inspect them. + +## Example + +```c +#include +#include + +#pragma STDC FENV_ACCESS ON +#pragma STDC FP_CONTRACT OFF + +int main(void) +{ + volatile double num = 1.0, den = 3.0; + feclearexcept(FE_ALL_EXCEPT); + volatile double x = num / den; + int inexact = fetestexcept(FE_INEXACT) != 0; + printf("1.0/3.0 = %.17g (%s)\n", x, inexact ? "FE_INEXACT raised" : "exact"); + return 0; +} +``` diff --git a/content/c-func.md b/content/c-func.md index d12e870..677a7c8 100644 --- a/content/c-func.md +++ b/content/c-func.md @@ -1,7 +1,3 @@ ---- -execute: true -show_assembly: true ---- ## What It Does `__func__` is a predefined identifier that expands to a string literal containing the name diff --git a/content/c-generic.md b/content/c-generic.md index 970e57e..d164f03 100644 --- a/content/c-generic.md +++ b/content/c-generic.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Generic(expression, type1: result1, type2: result2, ..., default: resultN)` selects one diff --git a/content/c-hex-float.md b/content/c-hex-float.md index 1d62df6..aba5774 100644 --- a/content/c-hex-float.md +++ b/content/c-hex-float.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Hexadecimal floating-point constants use the format `0xH.HHHpE` where `H` represents hexadecimal diff --git a/content/c-idempotent-qualifiers.md b/content/c-idempotent-qualifiers.md new file mode 100644 index 0000000..bf3b78d --- /dev/null +++ b/content/c-idempotent-qualifiers.md @@ -0,0 +1,34 @@ +## What It Does + +A type qualifier (`const`, `volatile`, or `restrict`) may appear more than once when qualifying a +single type, whether written directly or introduced through one or more typedefs. The redundant +occurrences carry no additional meaning. The resulting type is the same as if the qualifier appeared +only once. In C89, duplicating a qualifier was a constraint violation that required a diagnostic. + +## Why It Matters + +The rule lets qualification compose safely when part of a type comes from a typedef. When a +qualifier is hidden inside a typedef defined in a header, code that wants to add that qualifier +cannot tell whether it is already present short of trial and error. Under the C89 one-qualifier-only +constraint, applying `const` or `volatile` to such a type could produce a spurious diagnostic +depending on the header's internals. Collapsing duplicates to a single occurrence lets a typedef'd +type be further qualified unconditionally. It also lets an implementation make a typedef carry a +qualifier, such as defining `sig_atomic_t` as a volatile type, without breaking callers that also +apply the qualifier. + +## Example + +```c +#include + +typedef const int cint; + +/* const appears once via the typedef and once directly */ +const cint x = 42; + +int main(void) +{ + printf("%d\n", x); + return 0; +} +``` diff --git a/content/c-implicit-return-main.md b/content/c-implicit-return-main.md new file mode 100644 index 0000000..8abf5ac --- /dev/null +++ b/content/c-implicit-return-main.md @@ -0,0 +1,29 @@ +## What It Does + +When the return type of `main` is compatible with `int`, reaching the closing brace that terminates +`main` without executing a `return` statement returns a value of `0` to the host environment, +exactly as if `return 0;` had run. Zero denotes successful termination. A return from the initial +call to `main` is equivalent to calling `exit` with the returned value as its argument. If `main`'s +return type is not compatible with `int`, the status returned to the host environment is +unspecified, and this guarantee does not apply. + +## Why It Matters + +Without the rule, a `main` that ends without an explicit `return` would hand an indeterminate exit +status to the host environment, so even short programs had to write `return 0;` purely to obtain a +deterministic, successful status. Fixing the implicit value at `0` matches the common intent and +removes that boilerplate. The behavior is restricted to `main` whose return type is compatible with +`int` because a fixed integer `0` is meaningful only for an `int`-returning function; for any other +return type the standard leaves the status unspecified rather than inventing a conversion. + +## Example + +```c +#include + +int main(void) +{ + printf("reached the end of main\n"); + /* No return statement: the exit status is implicitly 0 (success). */ +} +``` diff --git a/content/c-inline.md b/content/c-inline.md index 2b08f2b..4e0133d 100644 --- a/content/c-inline.md +++ b/content/c-inline.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does `inline` serves two purposes: it suggests that the compiler substitute the function body at diff --git a/content/c-integer-division-truncation.md b/content/c-integer-division-truncation.md new file mode 100644 index 0000000..2010e08 --- /dev/null +++ b/content/c-integer-division-truncation.md @@ -0,0 +1,34 @@ +## What It Does + +For the `/` and `%` operators on signed integer operands, the result of `/` is the algebraic +quotient with any fractional part discarded, so it truncates toward zero. The `%` operator is +defined so that `(a/b)*b + a%b == a` holds, which makes the sign of the remainder follow the +dividend. So `-7/3` yields `-2` and `-7%3` yields `-1`, while `7/-3` yields `-2` and `7%-3` yields +`1`. Division by zero remains undefined behavior. The `div`, `ldiv`, and `lldiv` library functions +share the same truncating semantics and return the quotient and remainder together. + +## Why It Matters + +Previously, when a division was inexact and either operand was negative, an implementation could +round the quotient up or down, and the sign of the remainder was implementation-defined. That +latitude let a compiler map `/` directly onto whatever the target instruction set did natively, +avoiding extra code to normalize the negative cases. The cost was that identical source produced +different results across platforms, and the behavior diverged from Fortran, which always truncates +toward zero. Fixing the result to truncation toward zero makes signed integer division portable and +predictable, and the run-time overhead of enforcing it was judged acceptable. + +## Example + +```c +#include + +int main(void) +{ + printf("-7/3 = %d, -7%%3 = %d\n", -7 / 3, -7 % 3); + printf(" 7/-3 = %d, 7%%-3 = %d\n", 7 / -3, 7 % -3); + + int a = -7, b = 3; + printf("identity holds: %d\n", (a / b) * b + a % b == a); + return 0; +} +``` diff --git a/content/c-line-comments.md b/content/c-line-comments.md index dbaa754..ff86bc4 100644 --- a/content/c-line-comments.md +++ b/content/c-line-comments.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Single-line comments beginning with `//` extend to the end of the line. Everything from `//` diff --git a/content/c-mixed-declarations.md b/content/c-mixed-declarations.md new file mode 100644 index 0000000..3612295 --- /dev/null +++ b/content/c-mixed-declarations.md @@ -0,0 +1,39 @@ +## What It Does + +Inside a block, declarations and statements may appear in any order, freely interleaved. C89 +required every declaration in a block to precede all statements; C99 removes that restriction. A +compound statement becomes a sequence of block items, each of which is either a declaration or a +statement. The scope of a declared identifier still begins at its declaration, so code preceding the +declaration cannot refer to the identifier by name even though the object exists once the block is +entered. + +## Why It Matters + +C89's rule forced all locals to the top of a block, before any code could produce a meaningful value +to initialize them with. Declaring at the point of first use lets initialization sit next to the +computation that supplies the value, and keeps each variable's live region as small as the code that +needs it. Scope beginning at the declaration is what makes this safe. Earlier code cannot +accidentally name an identifier before it is introduced. It also composes with variable-length +arrays, whose size expression is evaluated when the declaration is reached during execution. + +## Example + +```c +#include + +int main(void) +{ + int values[] = {3, 7, 2, 8}; + int n = 4; + + int sum = 0; + for (int i = 0; i < n; i++) + sum += values[i]; + + /* declaration appears after statements in the same block */ + double average = (double)sum / n; + printf("sum = %d, average = %.2f\n", sum, average); + + return 0; +} +``` diff --git a/content/c-nodiscard.md b/content/c-nodiscard.md new file mode 100644 index 0000000..c8c25cf --- /dev/null +++ b/content/c-nodiscard.md @@ -0,0 +1,37 @@ +## What It Does + +`[[nodiscard]]` marks a function whose return value is not meant to be ignored; it may also be +applied to a structure, union, or enumeration definition. When a call to such a function appears as +a discarded-value expression, the implementation is encouraged to emit a diagnostic. That +encouragement excludes an explicit cast to `void`, which gives callers a way to mark the omission as +deliberate. + +## Why It Matters + +A declaration cannot express that ignoring a function's result is a mistake, and the function's +author is generally the one positioned to know whether it is. Some results are safe to drop, like +the character count from `printf`; others likely signal a bug when discarded, like the pointer from +`malloc`. Diagnosing every ignored result would produce too many false positives to be on by +default, so the check is opt-in. The author marks the specific functions where discarding the result +is probably an error. Casting the call to `void` lets a caller drop the result deliberately without +the diagnostic. + +## Example + +```c +#include + +[[nodiscard]] int compute(int x) +{ + return x * 2; +} + +int main(void) +{ + int value = compute(21); + printf("%d\n", value); + + (void)compute(10); // deliberate: the cast suppresses the diagnostic + compute(5); // diagnosed: result silently dropped +} +``` diff --git a/content/c-non-constant-initializers.md b/content/c-non-constant-initializers.md new file mode 100644 index 0000000..6ec0710 --- /dev/null +++ b/content/c-non-constant-initializers.md @@ -0,0 +1,47 @@ +## What It Does + +Initializers for block-scope arrays, structures, and unions may use non-constant expressions +evaluated at run time, such as variables, arithmetic on them, and function calls. A whole-structure +expression, such as a call returning the appropriate structure type, is accepted as an automatic +structure initializer. Objects with static storage duration keep the older rule, so their +initializers must be constant expressions or string literals. + +## Why It Matters + +A block-scope aggregate is initialized when its block is entered, so generated code can compute the +initializer at run time, exactly like the element-by-element assignments a programmer would +otherwise write by hand. Nothing about that timing requires the values to be known during +translation, so a constant-expression restriction serves no purpose there and only forces verbose +assignment after the declaration. The restriction survives for static-storage objects because they +are initialized before program startup, where only translation-time-computable values exist. Earlier +C had confined automatic aggregates to constant initializers out of caution about pathological +cases; that caution proved unnecessary. + +## Example + +```c +#include + +struct point +{ + int x, y; +}; + +struct point make(int a, int b) +{ + return (struct point){a + b, a - b}; +} + +int main(void) +{ + int a = 3, b = 7; + int arr[3] = {a, b, a + b}; + struct point p = {a * 2, b - 1}; + struct point q = make(a, b); + + printf("%d %d %d\n", arr[0], arr[1], arr[2]); + printf("%d %d\n", p.x, p.y); + printf("%d %d\n", q.x, q.y); + return 0; +} +``` diff --git a/content/c-noreturn.md b/content/c-noreturn.md index 5c6d07f..30a255d 100644 --- a/content/c-noreturn.md +++ b/content/c-noreturn.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Noreturn` specifies that a function does not return to its caller. In C23, the `[[noreturn]]` diff --git a/content/c-nullptr.md b/content/c-nullptr.md index d42bbaa..709a6c5 100644 --- a/content/c-nullptr.md +++ b/content/c-nullptr.md @@ -1,7 +1,3 @@ ---- -execute: true -show_assembly: true ---- ## What It Does `nullptr` is a null pointer constant with type `nullptr_t`. It implicitly converts to any diff --git a/content/c-pragma-operator.md b/content/c-pragma-operator.md new file mode 100644 index 0000000..5c80dc4 --- /dev/null +++ b/content/c-pragma-operator.md @@ -0,0 +1,38 @@ +## What It Does + +`_Pragma(string-literal)` is a unary preprocessor operator. The operand is destringized. An `L` +prefix is dropped, the surrounding double-quotes are removed, and `\"` and `\\` become `"` and `\`. +The resulting characters are rescanned as preprocessing tokens and executed as if they formed the +tokens of a `#pragma` directive. The original four tokens (`_Pragma`, `(`, the string, `)`) are then +removed. Because it is an operator taking a string argument rather than a line-oriented directive, +it can appear in a macro replacement list and be produced by macro expansion. + +## Why It Matters + +A `#pragma` is a preprocessing directive, so it must occupy its own logical line, and the +preprocessor never emits directive lines from a macro body. That makes it impossible to wrap a +pragma inside a macro or build one from macro arguments. `_Pragma` expresses the same effect as an +operator whose operand is a string. Because macros can expand to operator expressions and can +stringize their arguments with `#`, a pragma can be packaged in a macro and parameterized. The +destringization rules exist so a pragma's own tokens, including quotes and backslashes, survive +inside the string literal and are recovered exactly before being processed. Which pragmas do +anything remains implementation-defined. + +## Example + +```c +#include + +#define DIAG(x) _Pragma(#x) + +int main(void) +{ + DIAG(GCC diagnostic push) + DIAG(GCC diagnostic ignored "-Wunused-variable") + int unused = 42; + DIAG(GCC diagnostic pop) + + printf("built cleanly with _Pragma from inside a macro\n"); + return 0; +} +``` diff --git a/content/c-quick-exit.md b/content/c-quick-exit.md index 7cd2a98..d2f8e66 100644 --- a/content/c-quick-exit.md +++ b/content/c-quick-exit.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `quick_exit()` terminates the program, calling functions registered with `at_quick_exit()` diff --git a/content/c-restrict.md b/content/c-restrict.md index 7565cdd..9a4791a 100644 --- a/content/c-restrict.md +++ b/content/c-restrict.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does `restrict` is a type qualifier for pointers that asserts the pointed-to object is accessed diff --git a/content/c-static-assert.md b/content/c-static-assert.md index d7f5bd2..8b25522 100644 --- a/content/c-static-assert.md +++ b/content/c-static-assert.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Static_assert(expression, message)` verifies a condition at compile time. If the expression diff --git a/content/c-thread-local.md b/content/c-thread-local.md index a317301..5e04186 100644 --- a/content/c-thread-local.md +++ b/content/c-thread-local.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `_Thread_local` specifies that a variable has thread storage duration. Each thread has its diff --git a/content/c-threads.md b/content/c-threads.md index d280f49..ed297bb 100644 --- a/content/c-threads.md +++ b/content/c-threads.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c11" ---- - ## What It Does `` provides thread management (`thrd_create()`, `thrd_join()`), mutexes (`mtx_init()`, diff --git a/content/c-timespec-get.md b/content/c-timespec-get.md new file mode 100644 index 0000000..23a9a2e --- /dev/null +++ b/content/c-timespec-get.md @@ -0,0 +1,37 @@ +## What It Does + +`timespec_get` fills a `struct timespec` with the current calendar time in a given time base, +returning that base on success and zero on failure. With the base `TIME_UTC`, `tv_sec` receives the +number of seconds since an implementation-defined epoch, truncated to a whole value, and `tv_nsec` +receives the nanoseconds, rounded to the resolution of the system clock. + +## Why It Matters + +C's other time facilities do not provide portable sub-second calendar time. The value from `time()` +has an unspecified encoding, and the range and precision of `time_t` are implementation-defined, so +portable code cannot rely on sub-second resolution or name its units. Obtaining a known resolution +required a platform-specific call such as POSIX `clock_gettime(CLOCK_REALTIME, ts)`. `timespec_get` +standardizes calendar time with an explicit nanoseconds field, and its `base` parameter allows an +implementation to offer time bases beyond the required `TIME_UTC` without a new function. + +## Example + +```c +#include +#include + +int main(void) +{ + struct timespec ts; + + if (timespec_get(&ts, TIME_UTC) == TIME_UTC) + { + printf("seconds: %lld\n", (long long)ts.tv_sec); + printf("nanoseconds: %ld\n", (long)ts.tv_nsec); + } + else + { + printf("timespec_get failed\n"); + } +} +``` diff --git a/content/c-translation-limits.md b/content/c-translation-limits.md new file mode 100644 index 0000000..6f48654 --- /dev/null +++ b/content/c-translation-limits.md @@ -0,0 +1,50 @@ +## What It Does + +C99 specifies the minimum capacities a conforming implementation must be able to translate and +execute in at least one program. These cover nesting depths, identifier significance, parameter and +argument counts, case labels, structure members, string literal length, object size, and more. C99 +raised most of these minima above their C89 values. Case labels in a switch went from 257 to 1023, +block nesting from 15 to 127, significant characters in an external identifier from 6 to 31, +characters in a string literal (after concatenation) from 509 to 4095, and bytes in a single object +from 32767 to 65535. Implementations should avoid imposing fixed limits whenever possible. + +## Why It Matters + +These minima define the largest program a portable source may assume every conforming compiler +accepts, so authors can size code to a known floor without testing each toolchain. They are +guarantees, not hard ceilings. The standard requires only that one program reaching each limit +translate and execute. Because resources like memory come from a shared pool, not all limits need +hold at once. The values are compromises between allowing reasonably large portable programs and not +burdening small implementations. C99 could raise them because the assumed minimum target memory rose +from 64K to 512K, and because small and embedded targets are now usually built with cross compilers +hosted on workstations. + +## Example + +```c +#include +#include + +int main(void) +{ + /* ~600-char literal: portable under C99 (min 4095), not C89 (509). */ + const char *s = "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789"; + + printf("length = %zu\n", strlen(s)); + return 0; +} +``` diff --git a/content/c-typeof.md b/content/c-typeof.md index 1c51a8e..c67e6a2 100644 --- a/content/c-typeof.md +++ b/content/c-typeof.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `typeof` and `typeof_unqual` are operators that yield the type of an expression or type name. diff --git a/content/c-uchar.md b/content/c-uchar.md new file mode 100644 index 0000000..912f71e --- /dev/null +++ b/content/c-uchar.md @@ -0,0 +1,49 @@ +## What It Does + +The `` header declares two unsigned integer types. `char16_t` (the same type as +`uint_least16_t`) holds 16-bit characters, and `char32_t` (the same type as `uint_least32_t`) holds +32-bit characters. The `u` and `U` prefixes create character constants and string literals of these +types. `u'x'` and `u"..."` produce `char16_t` data, while `U'x'` and `U"..."` produce `char32_t` +data. The header also declares restartable conversion functions (`mbrtoc16`, `c16rtomb`, `mbrtoc32`, +`c32rtomb`) between multibyte sequences and these types. + +## Why It Matters + +The only prior wide type, `wchar_t`, has an implementation-defined width (16-bit on some platforms, +32-bit on others) and an unspecified encoding, which makes it unusable when code needs a definite +Unicode representation. `char16_t` and `char32_t` guarantee widths of at least 16 and 32 bits, +giving named targets for UTF-16 and UTF-32 that do not depend on how `wchar_t` is configured. The +`u`/`U` prefixes let source text be stored directly in those types without manual encoding. Because +the encoding of these types remains technically implementation-defined, the `__STDC_UTF_16__` and +`__STDC_UTF_32__` macros, when defined as 1, let a program confirm that the UTF encodings are in +effect. The conversion functions carry an `mbstate_t` so fragmented multibyte input can be decoded +incrementally. + +## Example + +```c +#include +#include + +/* char16_t/char32_t from are the same types as + uint_least16_t/uint_least32_t, used directly here. */ +int main(void) +{ + uint_least16_t u16[] = u"C11"; + uint_least32_t u32[] = U"C11"; + uint_least32_t ch = U'*'; + + printf("u16:"); + for (int i = 0; u16[i]; i++) + printf(" %u", (unsigned)u16[i]); + printf("\nu32:"); + for (int i = 0; u32[i]; i++) + printf(" %u", (unsigned)u32[i]); + printf("\nchar: %u\n", (unsigned)ch); + +#ifdef __STDC_UTF_16__ + printf("UTF-16 guaranteed: %d\n", __STDC_UTF_16__); +#endif + return 0; +} +``` diff --git a/content/c-universal-character-names.md b/content/c-universal-character-names.md new file mode 100644 index 0000000..f1da827 --- /dev/null +++ b/content/c-universal-character-names.md @@ -0,0 +1,31 @@ +## What It Does + +C99 lets identifiers contain characters outside the basic source set through universal character +names. A universal character name is a backslash followed by `u` and four hexadecimal digits +(`\uXXXX`), or `U` and eight hexadecimal digits (`\UXXXXXXXX`), each naming an ISO/IEC 10646 code +point. A universal character name may appear anywhere in an identifier, except that an identifier +may not begin with an extended digit. Only the code points in the ranges listed in Annex D are +permitted. An implementation may also accept the corresponding raw native character directly, but +that acceptance is implementation-defined; the escape spelling is the portable form. + +## Why It Matters + +Through C95 the source character set for identifiers was effectively English, and a name using +national characters was not strictly conforming. Multibyte characters already allowed non-English +text in string literals and character constants, but that mechanism was implementation-dependent, +did not travel between heterogeneous environments, and did not cover identifiers at all. A universal +character name gives a spelling for any permitted code point using only basic source characters, so +a name such as größe reads the same regardless of source encoding or local character set. + +## Example + +```c +#include + +int main(void) +{ + int \u00FCber = 7; /* U+00FC: 'u' with diaeresis */ + printf("value = %d\n", \u00FCber); + return 0; +} +``` diff --git a/content/c-unreachable.md b/content/c-unreachable.md index e896a55..119c283 100644 --- a/content/c-unreachable.md +++ b/content/c-unreachable.md @@ -1,7 +1,3 @@ ---- -execute: true -show_assembly: true ---- ## What It Does `[[unsequenced]]` indicates that a function has no side effects and its return value depends diff --git a/content/c-va-opt.md b/content/c-va-opt.md index 2129441..13b10a0 100644 --- a/content/c-va-opt.md +++ b/content/c-va-opt.md @@ -1,8 +1,3 @@ ---- -execute: true -show_assembly: true ---- - ## What It Does `__VA_OPT__(content)` is a function-like macro that expands to its argument if `__VA_ARGS__` diff --git a/content/c-variadic-macros.md b/content/c-variadic-macros.md index 9a6514a..1f995f7 100644 --- a/content/c-variadic-macros.md +++ b/content/c-variadic-macros.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Variadic macros accept a variable number of arguments using `...` in the parameter list. diff --git a/content/c-vla.md b/content/c-vla.md index 9b140c9..89b7d52 100644 --- a/content/c-vla.md +++ b/content/c-vla.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Variable-length arrays (VLAs) have a size determined at runtime rather than compile time. diff --git a/content/c-vm-types.md b/content/c-vm-types.md index 2c806f2..03749f7 100644 --- a/content/c-vm-types.md +++ b/content/c-vm-types.md @@ -1,9 +1,3 @@ ---- -execute: true -show_assembly: true -flags: "-std=c99" ---- - ## What It Does Variably-modified types are types of variable-length arrays or types derived from VLAs, diff --git a/content/char8-t.md b/content/char8-t.md index dc3aba7..f9c1ae4 100644 --- a/content/char8-t.md +++ b/content/char8-t.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `char8_t` is a distinct fundamental type representing UTF-8 encoded character data. diff --git a/content/concepts.md b/content/concepts.md index dbfe90f..3102102 100644 --- a/content/concepts.md +++ b/content/concepts.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Concepts are named predicates that constrain template parameters. diff --git a/content/consteval.md b/content/consteval.md index 4c4f1ab..4408dfd 100644 --- a/content/consteval.md +++ b/content/consteval.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `consteval` declares an immediate function that must produce a compile-time constant. diff --git a/content/constexpr-containers.md b/content/constexpr-containers.md index e3f9f3f..9920f85 100644 --- a/content/constexpr-containers.md +++ b/content/constexpr-containers.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Most standard library containers and container adaptors are now usable in `constexpr` contexts. diff --git a/content/constexpr-exception-types.md b/content/constexpr-exception-types.md index e4b3c34..ecf28cd 100644 --- a/content/constexpr-exception-types.md +++ b/content/constexpr-exception-types.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Standard library exception types are now `constexpr`-compatible. diff --git a/content/constexpr-exceptions.md b/content/constexpr-exceptions.md index 887bbca..cad4bf8 100644 --- a/content/constexpr-exceptions.md +++ b/content/constexpr-exceptions.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does With this, exceptions may be thrown and caught during constant expression evaluation. diff --git a/content/constexpr-vector.md b/content/constexpr-vector.md index 7c533d8..77aa9f2 100644 --- a/content/constexpr-vector.md +++ b/content/constexpr-vector.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::vector` can be used in `constexpr` context: vectors can be created, modified, and destroyed during diff --git a/content/constexpr-virtual.md b/content/constexpr-virtual.md index 3424f57..c83d312 100644 --- a/content/constexpr-virtual.md +++ b/content/constexpr-virtual.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does With this, virtual function calls are permitted within constant expressions. diff --git a/content/constexpr-void-cast.md b/content/constexpr-void-cast.md new file mode 100644 index 0000000..d1e3664 --- /dev/null +++ b/content/constexpr-void-cast.md @@ -0,0 +1,64 @@ +## What It Does + +During constant evaluation, a `void*` may be converted to `T*` when it holds a null pointer value, +or points to an object whose type is *similar* to `T`, meaning the same type up to cv-qualification, +so a `Cow` can be recovered as `const Cow*`. Pointer-interconvertible types, base classes, and +unrelated types remain rejected. + +## Why It Matters + +Storing data behind a `void*` is a common type-erasure technique. Member functions moved into a +non-template base that holds a `void*` are instantiated once instead of once per specialization, +reducing template instantiations and symbol count. Recovering the original pointer needs a cast that +constant evaluation used to reject, so facilities built this way could not be `constexpr`; +permitting the cast lets types such as `std::format` and `std::any` be made `constexpr`. The two +exclusions have distinct reasons. Reinterpreting an object as an unrelated type is generally not +implementable, because constexpr evaluators model values rather than memory. Base classes are +excluded even though casting to a base is allowed during constant evaluation, because going to a +derived type and then its base need not yield the same address as casting to the base directly. + +## Example + +```cpp +#include +#include + +struct Sheep +{ + constexpr std::string_view speak() const + { + return "Baaaaaa"; + } +}; +struct Cow +{ + constexpr std::string_view speak() const + { + return "Mooo"; + } +}; + +class AnimalView +{ + const void *animal; + std::string_view (*speak_fn)(const void *); + + public: + template + constexpr AnimalView(const A &a) + : animal(&a), speak_fn([](const void *o) { return static_cast(o)->speak(); }) + { + } + + constexpr std::string_view speak() const + { + return speak_fn(animal); + } +}; + +int main() +{ + static_assert(AnimalView(Cow()).speak() == "Mooo"); + std::println("{}", AnimalView(Sheep()).speak()); +} +``` diff --git a/content/constexpr.md b/content/constexpr.md index 776c656..3fa472b 100644 --- a/content/constexpr.md +++ b/content/constexpr.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `constexpr` declares that a function or variable can be evaluated at compile time. diff --git a/content/constinit.md b/content/constinit.md index b146176..f0e89f1 100644 --- a/content/constinit.md +++ b/content/constinit.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `constinit` specifies that a variable with static or thread-local storage duration diff --git a/content/contracts.md b/content/contracts.md index 2656d28..42b0678 100644 --- a/content/contracts.md +++ b/content/contracts.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Contracts specify function preconditions (requirements on input), postconditions diff --git a/content/coroutines.md b/content/coroutines.md index f511f64..f9e2e05 100644 --- a/content/coroutines.md +++ b/content/coroutines.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Coroutines are functions that can suspend execution and resume at a later point. diff --git a/content/ctad.md b/content/ctad.md index 22172cb..470c872 100644 --- a/content/ctad.md +++ b/content/ctad.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Class template argument deduction (CTAD) allows the compiler to deduce template arguments for diff --git a/content/debugging.md b/content/debugging.md index 1d5ae72..210c760 100644 --- a/content/debugging.md +++ b/content/debugging.md @@ -1,8 +1,3 @@ ---- -executable: false -flags: "-lstdc++exp" ---- - ## What It Does The `` header provides portable utilities for debugger interaction. diff --git a/content/decltype.md b/content/decltype.md index e155911..1d9d225 100644 --- a/content/decltype.md +++ b/content/decltype.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `decltype(expr)` yields the type of its operand expression **without evaluating it**. diff --git a/content/defaulted-special-members.md b/content/defaulted-special-members.md index 3b2c833..d145819 100644 --- a/content/defaulted-special-members.md +++ b/content/defaulted-special-members.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The compiler can implicitly generate move constructors and move assignment operators that perform diff --git a/content/delete-reason.md b/content/delete-reason.md index 22467be..ef1511e 100644 --- a/content/delete-reason.md +++ b/content/delete-reason.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Deleted functions may specify a message string as an argument to the `delete` specifier. diff --git a/content/designated-initializers.md b/content/designated-initializers.md index 22d2475..2d03a65 100644 --- a/content/designated-initializers.md +++ b/content/designated-initializers.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Designated initializers initialize aggregate members by name using `.member = value` syntax. diff --git a/content/disallow-return-temporary-glvalue.md b/content/disallow-return-temporary-glvalue.md index 502c43e..db48aa2 100644 --- a/content/disallow-return-temporary-glvalue.md +++ b/content/disallow-return-temporary-glvalue.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does `&&` and `const&` references can bind to temporary objects. diff --git a/content/embed.md b/content/embed.md index b1b0f29..d023327 100644 --- a/content/embed.md +++ b/content/embed.md @@ -1,7 +1,3 @@ ---- -show_only: true ---- - ## What It Does `#embed` is a preprocessor directive that embeds the contents of a binary file as a comma-separated list of integer literals. diff --git a/content/enumerate.md b/content/enumerate.md index 66fa921..5338bf2 100644 --- a/content/enumerate.md +++ b/content/enumerate.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `views::enumerate()` produces a range of tuples where each tuple contains an index and the corresponding element from the source range. diff --git a/content/execution.md b/content/execution.md index c00b7fa..5c189d0 100644 --- a/content/execution.md +++ b/content/execution.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::execution` defines a framework for asynchronous and parallel computation based on three core abstractions: senders (represent deferred work), receivers (consume results), and schedulers (control execution context). diff --git a/content/expansion-statements-library-support.md b/content/expansion-statements-library-support.md index 7fbfb50..b3da03c 100644 --- a/content/expansion-statements-library-support.md +++ b/content/expansion-statements-library-support.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::integer_sequence` can now be used in `template for` to conveniently write a loop diff --git a/content/expansion-statements.md b/content/expansion-statements.md index ee433d4..075988e 100644 --- a/content/expansion-statements.md +++ b/content/expansion-statements.md @@ -1,8 +1,3 @@ ---- -execute: true -flags: "-freflection" ---- - ## What It Does `template for` is a new statement that iterates over compile-time ranges, expanding the loop diff --git a/content/expected.md b/content/expected.md index 54b05da..bbb9d6a 100644 --- a/content/expected.md +++ b/content/expected.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::expected` is a class template that stores either a value of type `T` or an error of type `E`. diff --git a/content/filesystem.md b/content/filesystem.md index cadd2b0..e8d512c 100644 --- a/content/filesystem.md +++ b/content/filesystem.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does `std::filesystem` provides facilities for path manipulation, file status queries, directory iteration, and file system modification operations. diff --git a/content/flat-map.md b/content/flat-map.md index 74c9ba0..5325667 100644 --- a/content/flat-map.md +++ b/content/flat-map.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::flat_map` and `std::flat_set` are associative containers that store elements in contiguous storage (typically `std::vector`) rather than tree nodes. diff --git a/content/fold-expressions.md b/content/fold-expressions.md index ccaf5bc..cbf0e32 100644 --- a/content/fold-expressions.md +++ b/content/fold-expressions.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Fold expressions apply a binary operator to all elements of a parameter pack in a single expression. diff --git a/content/format.md b/content/format.md index a00fcb2..e15aa4c 100644 --- a/content/format.md +++ b/content/format.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::format()` performs type-safe string formatting using replacement fields with format specifications. diff --git a/content/generator.md b/content/generator.md index f334e26..271f5b7 100644 --- a/content/generator.md +++ b/content/generator.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::generator` is a coroutine type for lazy sequence generation. diff --git a/content/generic-lambdas.md b/content/generic-lambdas.md index b73cfed..89ca1d9 100644 --- a/content/generic-lambdas.md +++ b/content/generic-lambdas.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Generic lambdas declare parameters with `auto`, producing a function call operator template. The compiler instantiates the appropriate specialization based on the argument types at each call site, so you don't need explicit template syntax in the lambda definition. diff --git a/content/guaranteed-copy-elision.md b/content/guaranteed-copy-elision.md index 2adf384..f00024b 100644 --- a/content/guaranteed-copy-elision.md +++ b/content/guaranteed-copy-elision.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does In C++17 and newer, returning a [prvalue](https://cppreference.com/cpp/language/value_category) of the same type as the function return type, diff --git a/content/hardening-additions.md b/content/hardening-additions.md index 758f83f..d95f736 100644 --- a/content/hardening-additions.md +++ b/content/hardening-additions.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Additional standard library functions now have hardened preconditions that perform runtime diff --git a/content/hardening.md b/content/hardening.md index 156a174..56043f9 100644 --- a/content/hardening.md +++ b/content/hardening.md @@ -1,8 +1,3 @@ ---- -execute: true -flags: "-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS" ---- - ## What It Does Standard library hardening introduces runtime validation for operations with invalid preconditions. This includes bounds checking for container element access (`std::vector`, `std::span`, `std::string_view`) and state validation for types with invalid access conditions (`std::optional`, `std::expected`). When a contract violation is detected, the program terminates deterministically instead of invoking undefined behavior. diff --git a/content/hive.md b/content/hive.md index a88a91f..9b21074 100644 --- a/content/hive.md +++ b/content/hive.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::hive` is a container designed for high-frequency insertion and erasure operations. diff --git a/content/if-consteval.md b/content/if-consteval.md index 1977256..1015c83 100644 --- a/content/if-consteval.md +++ b/content/if-consteval.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `if consteval` detects whether the current execution context is compile-time evaluation. diff --git a/content/if-constexpr.md b/content/if-constexpr.md index 59fe869..4a06d90 100644 --- a/content/if-constexpr.md +++ b/content/if-constexpr.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `if constexpr` evaluates a boolean condition at compile time and discards the non-selected branch. diff --git a/content/initializer-lists.md b/content/initializer-lists.md index 67a8528..4bf80d3 100644 --- a/content/initializer-lists.md +++ b/content/initializer-lists.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::initializer_list` allows functions and constructors to accept brace-enclosed lists of values. diff --git a/content/inline-variables.md b/content/inline-variables.md index a118150..b2ceb17 100644 --- a/content/inline-variables.md +++ b/content/inline-variables.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The `inline` specifier can be applied to variables, giving them the same linkage semantics as inline functions. diff --git a/content/inplace-vector.md b/content/inplace-vector.md index 2449e9b..6daaeb1 100644 --- a/content/inplace-vector.md +++ b/content/inplace-vector.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::inplace_vector` is a dynamically-resizable sequence container with a fixed maximum capacity `N`. diff --git a/content/jthread.md b/content/jthread.md index c93e339..437f0a4 100644 --- a/content/jthread.md +++ b/content/jthread.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::jthread` is a thread wrapper that automatically joins upon destruction. diff --git a/content/lambda-omit-parens.md b/content/lambda-omit-parens.md new file mode 100644 index 0000000..0382774 --- /dev/null +++ b/content/lambda-omit-parens.md @@ -0,0 +1,35 @@ +## What It Does + +A lambda that takes no parameters may omit the empty parameter list even when it carries a +specifier. `[]{ }` was always valid, but `[] mutable { }` was not, because adding `mutable` made the +parentheses mandatory again. The relaxation covers lambda template parameters, `constexpr`, +`mutable`, `consteval`, exception specifications and `noexcept`, attributes, trailing return types, +and `requires` clauses. + +## Why It Matters + +A lambda with no parameters may already omit the parameter list, because a lambda without a +declarator behaves as if it were `()`. Adding a specifier such as `mutable` used to reverse that and +require the empty `()` again, an inconsistency that was a frequent source of syntax errors. Making +the parentheses optional in every case, not only when no specifier is present, removes the special +case. Existing code is unaffected. + +## Example + +```cpp +#include +#include + +int main() +{ + auto grow = [s = std::string("abc")] mutable { + s += "d"; + return s; + }; + + auto answer = [] noexcept { return 42; }; + + std::println("{}", grow()); + std::println("{}", answer()); +} +``` diff --git a/content/lambdas.md b/content/lambdas.md index a4610eb..ea15220 100644 --- a/content/lambdas.md +++ b/content/lambdas.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Lambda expressions define anonymous function objects inline. They capture variables from the enclosing scope for use within the function body, and are employed in callbacks, algorithms, and contexts requiring locally-scoped function objects. diff --git a/content/likely-unlikely.md b/content/likely-unlikely.md index 13445ff..c9d1ab7 100644 --- a/content/likely-unlikely.md +++ b/content/likely-unlikely.md @@ -1,8 +1,3 @@ ---- -execute: false -show_assembly: true ---- - ## What It Does The `[[likely]]` and `[[unlikely]]` attributes indicate to the compiler the relative probability diff --git a/content/literal-suffix-size-t.md b/content/literal-suffix-size-t.md index 505f6c9..753759a 100644 --- a/content/literal-suffix-size-t.md +++ b/content/literal-suffix-size-t.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The literal suffixes `uz` (or `UZ`) and `z` (or `Z`) produce values of type `size_t` and the corresponding diff --git a/content/make-format-args-lvalue.md b/content/make-format-args-lvalue.md index f55cfd9..4a8d785 100644 --- a/content/make-format-args-lvalue.md +++ b/content/make-format-args-lvalue.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does `std::make_format_args()` now accepts only lvalue references instead of forwarding references. diff --git a/content/make-unique.md b/content/make-unique.md index 5b75dba..5d573ee 100644 --- a/content/make-unique.md +++ b/content/make-unique.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::make_unique()` constructs a `std::unique_ptr` by allocating storage, constructing the object diff --git a/content/mdspan.md b/content/mdspan.md index 5d4f3f0..a454bf8 100644 --- a/content/mdspan.md +++ b/content/mdspan.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::mdspan` is a non-owning view over contiguous data providing multidimensional array access semantics. It encapsulates a pointer to data with layout mapping that translates multidimensional indices to memory offsets. The layout policy determines the memory access pattern (row-major or column-major). diff --git a/content/modules.md b/content/modules.md index d85e359..c03d3d4 100644 --- a/content/modules.md +++ b/content/modules.md @@ -1,7 +1,3 @@ ---- -show_only: true ---- - ## What It Does Modules provide an encapsulation mechanism that replaces textual inclusion of header files with explicit interface declarations. An `export` declaration specifies the module's public interface; `import` declarations make these declarations available to consuming translation units. Modules are compiled once, cached as binary metadata, and provide namespace isolation that prevents macro leakage and implementation detail exposure. diff --git a/content/more-constexpr-cmath.md b/content/more-constexpr-cmath.md index e976f3d..6ca9997 100644 --- a/content/more-constexpr-cmath.md +++ b/content/more-constexpr-cmath.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Most functions in the `` and `` headers are made `constexpr`. diff --git a/content/multidim-subscript.md b/content/multidim-subscript.md index 41ca319..65ab546 100644 --- a/content/multidim-subscript.md +++ b/content/multidim-subscript.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The subscript operator `operator[]` accepts multiple arguments. The syntax `m[i, j]` performs direct multidimensional indexing without chained bracket operations or function call syntax. Within brackets, the comma functions as a parameter separator rather than the comma operator. diff --git a/content/nested-namespaces.md b/content/nested-namespaces.md new file mode 100644 index 0000000..d6aedb9 --- /dev/null +++ b/content/nested-namespaces.md @@ -0,0 +1,46 @@ +## What It Does + +A namespace definition may use a qualified name to open several nested namespaces at once. +`namespace A::B::C { }` is equivalent to three nested `namespace` blocks, and the names behave +identically either way. + +## Why It Matters + +Writing each level of a deep namespace as its own block requires a separate `namespace` line and a +closing brace for every level. The qualified form expresses the same nesting in a single +declaration. It is defined entirely by that equivalence and adds no new scoping behavior, so the two +forms are interchangeable and code that compiled before is unaffected. + +## Example + +```cpp +#include + +namespace app::net::http +{ +int status() +{ + return 200; +} +} // namespace app::net::http + +namespace app +{ +namespace net +{ +namespace ftp +{ +int status() +{ + return 220; +} +} // namespace ftp +} // namespace net +} // namespace app + +int main() +{ + std::println("{}", app::net::http::status()); + std::println("{}", app::net::ftp::status()); +} +``` diff --git a/content/noexcept.md b/content/noexcept.md index b9cbc23..f838183 100644 --- a/content/noexcept.md +++ b/content/noexcept.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The `noexcept` specifier declares that a function does not throw exceptions. diff --git a/content/nullptr.md b/content/nullptr.md index 127fb4b..432c618 100644 --- a/content/nullptr.md +++ b/content/nullptr.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `nullptr` is a keyword of type `std::nullptr_t` that represents a null pointer. diff --git a/content/optional-ref.md b/content/optional-ref.md index 822ec99..354fa2c 100644 --- a/content/optional-ref.md +++ b/content/optional-ref.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::optional` is a specialization of `std::optional` containing either a reference to an object diff --git a/content/optional.md b/content/optional.md index 55a04df..7361851 100644 --- a/content/optional.md +++ b/content/optional.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::optional` is a class template containing either a value of type `T` or no value. diff --git a/content/override-final.md b/content/override-final.md index 0fc714e..88a95db 100644 --- a/content/override-final.md +++ b/content/override-final.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `override` explicitly marks a member function as overriding a virtual function in a base class; diff --git a/content/oxford-variadic-comma.md b/content/oxford-variadic-comma.md index f7671d3..97d4770 100644 --- a/content/oxford-variadic-comma.md +++ b/content/oxford-variadic-comma.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does This proposal makes use of a variadic ellipsis (`...`) deprecated, diff --git a/content/pack-indexing.md b/content/pack-indexing.md index 83c4c26..84459bb 100644 --- a/content/pack-indexing.md +++ b/content/pack-indexing.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Pack indexing provides direct access to individual elements of a parameter pack via the `...[N]` syntax. The index is a compile-time constant expression. This eliminates the need for recursive template instantiation or `std::tuple`-based indirection to extract specific pack elements. diff --git a/content/parallel-algorithms.md b/content/parallel-algorithms.md index 511cbbc..e4380e2 100644 --- a/content/parallel-algorithms.md +++ b/content/parallel-algorithms.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does Standard algorithms in ``, ``, and `` accept an execution policy as their first argument. diff --git a/content/placeholder-variable.md b/content/placeholder-variable.md index 1e566f7..9eefde6 100644 --- a/content/placeholder-variable.md +++ b/content/placeholder-variable.md @@ -1,7 +1,3 @@ ---- -show_only: true ---- - ## What It Does The identifier `_` serves as a placeholder variable name indicating intentional value discard. diff --git a/content/print.md b/content/print.md index d1dbee4..b6854f4 100644 --- a/content/print.md +++ b/content/print.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::print()` and `std::println()` perform type-safe formatted output using the same format diff --git a/content/range-for.md b/content/range-for.md index 464a6ee..28e7565 100644 --- a/content/range-for.md +++ b/content/range-for.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `for (auto& x : container)` iterates over all elements of a range. diff --git a/content/ranges-to.md b/content/ranges-to.md index 001d148..bff15ff 100644 --- a/content/ranges-to.md +++ b/content/ranges-to.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `ranges::to()` materializes a range into a concrete container of the specified type. diff --git a/content/ranges.md b/content/ranges.md index 5d48615..4fc9ee2 100644 --- a/content/ranges.md +++ b/content/ranges.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Ranges encapsulate sequences of elements as single objects with `begin()` and `end()` accessors. diff --git a/content/reflection-annotations.md b/content/reflection-annotations.md new file mode 100644 index 0000000..d95b8f8 --- /dev/null +++ b/content/reflection-annotations.md @@ -0,0 +1,47 @@ +## What It Does + +An annotation attaches a compile-time value to a declaration where reflection can read it back. It +is written inside attribute brackets with a leading `=`, as in `[[= 1]] void f();`. Annotations may +be applied to a declaration of a type, type alias, variable, function, namespace, enumerator, +base-specifier, or non-static data member. The value is the result of `std::meta::reflect_constant` +applied to the given constant expression, and `std::meta::annotations_of` retrieves the annotations +of a reflected entity. + +## Why It Matters + +Reflection can enumerate what a class contains, but not what its members are intended for. It cannot +tell which field is a command-line flag, or which function is a test to parametrize. Ordinary +attributes appear to be the place to record that, but they are ignorable, so an implementation may +discard them, and they carry no value that reflection could return. An annotation is therefore a +distinct construct whose value is preserved and readable through reflection. It is written as an +attribute of the form `= expr`, so it reuses attribute placement but stays separate from attributes +proper. + +## Example + +```cpp +#include +#include + +struct Column +{ + int width; +}; + +struct Row +{ + [[= Column(8)]] int id; + [[= Column(24)]] int name; +}; + +int main() +{ + template for (constexpr auto member : define_static_array(std::meta::nonstatic_data_members_of( + ^^Row, std::meta::access_context::current()))) + { + constexpr auto anns = define_static_array(std::meta::annotations_of(member)); + constexpr auto col = std::meta::extract(anns[0]); + std::println("{} -> width {}", std::meta::identifier_of(member), col.width); + } +} +``` diff --git a/content/reflection.md b/content/reflection.md index ea78f5e..5490a43 100644 --- a/content/reflection.md +++ b/content/reflection.md @@ -1,8 +1,3 @@ ---- -execute: true -flags: "-freflection" ---- - ## What It Does Reflection provides compile-time introspection and manipulation of program structure. diff --git a/content/rvalue-references.md b/content/rvalue-references.md index 7219934..0d3291f 100644 --- a/content/rvalue-references.md +++ b/content/rvalue-references.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Rvalue references (`T&&`) distinguish temporary objects from lvalues. diff --git a/content/scoped-enums.md b/content/scoped-enums.md index d5b6f83..d9805ba 100644 --- a/content/scoped-enums.md +++ b/content/scoped-enums.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `enum class` (scoped enumeration) defines enumerators that are scoped to the enum type and do not diff --git a/content/simd.md b/content/simd.md index 00204a5..4ea7153 100644 --- a/content/simd.md +++ b/content/simd.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does `std::simd` provides portable SIMD (Single Instruction, Multiple Data) vector types. diff --git a/content/source-location.md b/content/source-location.md index e760374..396690b 100644 --- a/content/source-location.md +++ b/content/source-location.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::source_location` encapsulates source code metadata diff --git a/content/span.md b/content/span.md index 81abb68..d5fb4d3 100644 --- a/content/span.md +++ b/content/span.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::span` is a non-owning view over a contiguous sequence of elements. diff --git a/content/stacktrace.md b/content/stacktrace.md index 3577abc..e017232 100644 --- a/content/stacktrace.md +++ b/content/stacktrace.md @@ -1,8 +1,3 @@ ---- -execute: true -flags: "-lstdc++exp" ---- - ## What It Does `std::stacktrace` captures the current call stack at runtime. diff --git a/content/static-assert-message.md b/content/static-assert-message.md index 4177af4..2299f67 100644 --- a/content/static-assert-message.md +++ b/content/static-assert-message.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does `static_assert` can now accept a user-generated message instead of requiring a string literal. diff --git a/content/static-call-operator.md b/content/static-call-operator.md index a9c89ed..1135804 100644 --- a/content/static-call-operator.md +++ b/content/static-call-operator.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The function call operator `operator()` may be declared `static`. Stateless function diff --git a/content/static-subscript-operator.md b/content/static-subscript-operator.md index a5d19a7..6923930 100644 --- a/content/static-subscript-operator.md +++ b/content/static-subscript-operator.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `static operator[]` allows the subscript operator to be declared as a static member function. diff --git a/content/string-contains.md b/content/string-contains.md new file mode 100644 index 0000000..9766c51 --- /dev/null +++ b/content/string-contains.md @@ -0,0 +1,37 @@ +## What It Does + +`contains` reports whether a string holds a given substring, returning `bool`. It is a member of +both `basic_string` and `basic_string_view`, and overloads accept a `basic_string_view`, a pointer +to a null-terminated string, or a single character. The functions are `constexpr`, so the check can +run during constant evaluation. + +## Why It Matters + +Testing for a substring previously meant `haystack.find(needle) != std::string::npos`, a presence +check written as an inequality against the sentinel for "not found", which the reader has to +translate back. The C function `strstr` works only on null-terminated data. A free function such as +`boost::contains` gives no clue whether the substring or the haystack comes first. A member +`contains` states the intent directly and fixes the order. It searches for a substring, a different +operation from the `contains` added to the associative containers in C++20, where the argument is a +key. + +## Example + +```cpp +#include +#include +#include + +int main() +{ + std::string haystack = "no place for needles"; + + std::println("{}", haystack.contains("needle")); + std::println("{}", haystack.contains('z')); + + std::string_view view = haystack; + std::println("{}", view.contains("place")); + + static_assert(std::string_view("compile time").contains("time")); +} +``` diff --git a/content/string-view.md b/content/string-view.md index 5444bc0..c987db7 100644 --- a/content/string-view.md +++ b/content/string-view.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::string_view` is a non-owning reference to a contiguous character sequence. diff --git a/content/structured-bindings.md b/content/structured-bindings.md index d50fd64..de0c57e 100644 --- a/content/structured-bindings.md +++ b/content/structured-bindings.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Structured bindings decompose tuples, pairs, arrays, and structs into named identifiers diff --git a/content/template-aliases.md b/content/template-aliases.md index be2200a..3d83e05 100644 --- a/content/template-aliases.md +++ b/content/template-aliases.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `template using Name = ...;` creates a template alias, a new name for an existing template or diff --git a/content/template-parameter-init.md b/content/template-parameter-init.md index fb5e2cf..f80499e 100644 --- a/content/template-parameter-init.md +++ b/content/template-parameter-init.md @@ -1,7 +1,3 @@ ---- -execute: false ---- - ## What It Does This change clarifies how class-type non-type template parameters are initialized. A temporary of diff --git a/content/three-way-comparison.md b/content/three-way-comparison.md index 6953550..893d28e 100644 --- a/content/three-way-comparison.md +++ b/content/three-way-comparison.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does The three-way comparison operator `<=>` computes the ordering relationship between two operands in diff --git a/content/to-chars.md b/content/to-chars.md index fb8e5f4..05cb305 100644 --- a/content/to-chars.md +++ b/content/to-chars.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::to_chars()` and `std::from_chars()` in `` convert between numeric values and character sequences. diff --git a/content/trivial-infinite-loops.md b/content/trivial-infinite-loops.md index cb4abb1..1a0f366 100644 --- a/content/trivial-infinite-loops.md +++ b/content/trivial-infinite-loops.md @@ -1,8 +1,3 @@ ---- -execute: false -show_assembly: true ---- - ## What It Does Trivial infinite loops (iteration statements with empty or side-effect-free bodies) are no diff --git a/content/using-enum.md b/content/using-enum.md index 724a319..de4472c 100644 --- a/content/using-enum.md +++ b/content/using-enum.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `using enum EnumType;` introduces all enumerators of a scoped enumeration into the current scope, diff --git a/content/va-opt.md b/content/va-opt.md new file mode 100644 index 0000000..5fb71af --- /dev/null +++ b/content/va-opt.md @@ -0,0 +1,32 @@ +## What It Does + +`__VA_OPT__(content)` may appear in the replacement list of a variadic macro. It expands to +`content` when the variable arguments, after substitution, consist of at least one preprocessing +token, and to nothing otherwise. Its usual job is to emit a separating comma only when arguments +actually follow it. The condition is about tokens, not about whether an argument was written. An +argument that is present but substitutes to nothing still suppresses the expansion. + +## Why It Matters + +A variadic macro that places `__VA_ARGS__` after a fixed argument needs a comma before it, but that +comma is wrong when no variable arguments follow. Take `#define F(X, ...) f(X, __VA_ARGS__)`. The +call `F(a, )` expands to `f(a, )`, whose trailing comma is a syntax error. The older rule that an +invocation supply at least as many commas as the macro has mandatory parameters made `F(a)` +ill-formed outright, so a macro like `ERROR(msg, ...)` could not be called with only its message. +`__VA_OPT__` ties the separator to whether the variable arguments expand to any tokens, so the comma +appears only when something follows it. + +## Example + +```cpp +#include + +#define LOG(fmt, ...) std::println("[log] " fmt __VA_OPT__(, ) __VA_ARGS__) + +int main() +{ + LOG("starting up"); + LOG("loaded {} items", 7); + LOG("{} of {} done", 3, 10); +} +``` diff --git a/content/variable-templates.md b/content/variable-templates.md new file mode 100644 index 0000000..194fc83 --- /dev/null +++ b/content/variable-templates.md @@ -0,0 +1,36 @@ +## What It Does + +A variable template defines a family of variables parameterized by template arguments. Writing +`template constexpr T pi = T(3.1415926535897932385L);` gives a distinct `pi` for every type +it is instantiated with. At namespace scope a variable template declares a variable; at class scope +it declares a static data member template. + +## Why It Matters + +C++ has no other direct way to write a constant that varies by type. Both older workarounds cost +something. A static data member of a class template must be defined a second time outside the class +once the constant is odr-used. A `constexpr` function template fixes how the value is delivered at +the point of definition. A const reference forces the constant into static storage, while returning +by value copies it at every use. Copying is free for builtin types but expensive for large class +types. A variable template defers that choice to each point of use. + +## Example + +```cpp +#include + +template +constexpr T pi = T(3.1415926535897932385L); + +template +T circular_area(T r) +{ + return pi * r * r; +} + +int main() +{ + std::println("{}", circular_area(2.0)); + std::println("{}", circular_area(2.0f)); +} +``` diff --git a/content/variadic-templates.md b/content/variadic-templates.md index 83914b1..419b2b8 100644 --- a/content/variadic-templates.md +++ b/content/variadic-templates.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does Variadic templates accept an arbitrary number of template parameters using `...` pack syntax. diff --git a/content/variant.md b/content/variant.md index 5e16a61..030bdb4 100644 --- a/content/variant.md +++ b/content/variant.md @@ -1,7 +1,3 @@ ---- -execute: true ---- - ## What It Does `std::variant` is a type-safe [tagged union](https://en.wikipedia.org/wiki/Tagged_union) that holds a diff --git a/features_c11.yaml b/features_c11.yaml index aa2186f..d44c9cf 100644 --- a/features_c11.yaml +++ b/features_c11.yaml @@ -73,13 +73,16 @@ features: - owcc - TinyCC - desc: "Unicode support (``, `u/U` prefixes)" + summary: "Unicode character types, literals, and conversion functions." paper: N1487 lib: true support: - GCC 4.7.1 - MSVC 14.20 - Clang 3.3 + content: c-uchar.md - desc: 'Exclusive create-and-open mode for `fopen()` ("x")' + summary: "Exclusive create-and-open mode for `fopen`." paper: N1339 lib: true support: @@ -87,6 +90,7 @@ features: - Clang 3.1 - MSVC 14.20 - Xcode 16.1 + content: c-fopen-exclusive.md - desc: "Quick exit (`quick_exit()`, `at_quick_exit()`)" paper: N1327 content: c-quick-exit.md @@ -98,16 +102,20 @@ features: - Xcode 16.1 - desc: "`timespec_get()` function" paper: N1499 + summary: "Calendar time with a nanoseconds field, in a chosen time base." lib: true support: - GCC 4.7.1 - Clang 3.3 - MSVC 14.20 - Xcode 16.1 + content: c-timespec-get.md - desc: "Macros for complex number types (`CMPLX`)" + summary: "Build complex values componentwise without NaN contamination." paper: N1464 lib: true support: - GCC 4.7.1 - Clang 3.3 - Xcode 16.1 + content: c-cmplx.md diff --git a/features_c23.yaml b/features_c23.yaml index 02149df..e8682eb 100644 --- a/features_c23.yaml +++ b/features_c23.yaml @@ -9,10 +9,12 @@ features: - Xcode 11.4 - desc: "`[[nodiscard]]`" paper: N2267 + summary: "Marks a return value that should not be ignored." support: - GCC 10 - Clang 9 - Xcode 11.4 + content: c-nodiscard.md - desc: "`[[maybe_unused]]`" paper: N2270 support: diff --git a/features_c99.yaml b/features_c99.yaml index 016bb55..987f501 100644 --- a/features_c99.yaml +++ b/features_c99.yaml @@ -1,12 +1,15 @@ --- features: - desc: "Universal-character-names in [identifiers](https://cppreference.com/c/language/identifiers)" + summary: "Non-basic characters in identifiers via universal-character-names." support: - GCC 3.1 - Clang - MSVC - Xcode + content: c-universal-character-names.md - desc: "Increased [translation limits](https://cppreference.com/c/language/identifiers#Translation_limits)" + summary: "Raised minimum translation limits for portable programs." paper: N590 support: - GCC @@ -14,6 +17,7 @@ features: - Xcode - owcc - TinyCC + content: c-translation-limits.md - desc: "`//` comments" paper: N644 content: c-line-comments.md @@ -86,19 +90,24 @@ features: - Xcode 14 - owcc 1.4 - desc: "Non-constant initializers" + summary: "Non-constant initializers for block-scope aggregates." support: - GCC - owcc (partial) hints: - target: owcc msg: "Requires -aa for wcc*." + content: c-non-constant-initializers.md - desc: "Idempotent cvr-qualifiers" + summary: "Repeated cvr-qualifiers on a type are idempotent." paper: N505 support: - GCC 3 - Clang - Xcode + content: c-idempotent-qualifiers.md - desc: "Trailing comma in _enumerator-list_" + summary: "A comma is allowed after the last enumerator." support: - GCC - Clang @@ -106,6 +115,7 @@ features: - Xcode - owcc - TinyCC + content: c-enum-trailing-comma.md - desc: "Hexadecimal [floating constants](https://cppreference.com/c/language/floating_constant)" paper: N308 content: c-hex-float.md @@ -125,17 +135,22 @@ features: - MSVC - Xcode 14 - desc: "Floating-point environment" + summary: "Runtime access to the floating-point environment." support: - GCC (partial) - Clang (partial) - Xcode 14 (partial) + content: c-fenv.md - desc: "Requiring truncation for divisions of signed integer types" + summary: "Signed integer division must truncate toward zero." paper: N617 support: - GCC - Clang - Xcode + content: c-integer-division-truncation.md - desc: "Implicit `return 0;` in the [`main()` function](https://cppreference.com/c/language/main_function)" + summary: "Reaching the end of `main` returns zero implicitly." support: - GCC - Clang @@ -143,7 +158,9 @@ features: - Xcode - owcc 1.5 - TinyCC + content: c-implicit-return-main.md - desc: "Declarations and statements in mixed order" + summary: "Declarations and statements may interleave within a block." paper: N740 support: - GCC 3 @@ -152,7 +169,9 @@ features: - Xcode 14 - owcc - TinyCC + content: c-mixed-declarations.md - desc: "_init-statement_ in `for` loops" + summary: "Declaring loop counters in a `for` statement's init clause." support: - GCC - Clang @@ -160,6 +179,7 @@ features: - Xcode - owcc - TinyCC + content: c-for-loop-declarations.md - desc: "`inline` functions" paper: N741 content: c-inline.md @@ -181,10 +201,12 @@ features: - owcc 1.2 - TinyCC - desc: "Cvr-qualifiers and `static` in `[]` within function declarations" + summary: "Qualifiers and `static` array sizes in function parameters." support: - GCC 3.1 - Clang - Xcode + content: c-array-parameter-qualifiers.md - desc: "[Variadic macros](https://cppreference.com/c/preprocessor/replace)" paper: N707 content: c-variadic-macros.md @@ -196,6 +218,7 @@ features: - owcc - TinyCC - desc: "`_Pragma` preprocessor operator" + summary: "Emits a pragma from within a macro expansion." paper: N634 support: - GCC 3 @@ -206,7 +229,9 @@ features: hints: - target: MSVC msg: "Requires /std:c11 or later." + content: c-pragma-operator.md - desc: "Standard pragmas for floating-point evaluation" + summary: "Standard `STDC` pragmas controlling floating-point code generation." paper: - N631 - N696 @@ -221,3 +246,4 @@ features: msg: "`STDC FENV_ACCESS ON` is not supported." - target: owcc msg: "`parsed, but does not change the code." + content: c-fp-pragmas.md diff --git a/features_cpp14.yaml b/features_cpp14.yaml index da72078..4290d3f 100644 --- a/features_cpp14.yaml +++ b/features_cpp14.yaml @@ -66,6 +66,7 @@ features: - desc: "[Variable templates](https://cppreference.com/cpp/language/variable_template)" paper: N3651 + summary: "Variables parameterized by type, without a wrapping class or function." support: - GCC 5 - Clang 3.4 @@ -74,6 +75,7 @@ features: ftm: - name: __cpp_variable_templates value: 201304L + content: variable-templates.md - desc: "Relaxed `constexpr` restrictions" paper: N3652 diff --git a/features_cpp17.yaml b/features_cpp17.yaml index 5ffa0cf..03fe34e 100644 --- a/features_cpp17.yaml +++ b/features_cpp17.yaml @@ -32,6 +32,7 @@ features: - Clang 3.6 - MSVC 14.0 - Xcode + content: nested-namespaces.md - desc: "Extending `static_assert`, v2" paper: N3928 diff --git a/features_cpp20.yaml b/features_cpp20.yaml index 8fede63..3f4a4c6 100644 --- a/features_cpp20.yaml +++ b/features_cpp20.yaml @@ -26,6 +26,7 @@ features: - desc: "`__VA_OPT__`" paper: [P0306, P1042] + summary: "Emit a comma in a variadic macro only when arguments follow." support: - GCC 8 (partial) - GCC 10 (partial) @@ -38,6 +39,7 @@ features: msg: "Designated initializers are supported, except #__VA_OPT__ support. __VA_OPT__ is supported though." - target: GCC 10 msg: "No placemarker token handling changes" + content: va-opt.md - desc: "Designated initializers" paper: P0329 diff --git a/features_cpp23.yaml b/features_cpp23.yaml index f357e84..7189ba5 100644 --- a/features_cpp23.yaml +++ b/features_cpp23.yaml @@ -15,6 +15,7 @@ features: - desc: "`std::basic_string::contains()` and `std::basic_string_view::contains()`" paper: P1679 + summary: "Test for a substring directly instead of comparing find() against npos." lib: true support: - GCC 11 @@ -24,6 +25,7 @@ features: ftm: - name: __cpp_lib_string_contains value: 202011L + content: string-contains.md - desc: "``" paper: P0881 @@ -74,6 +76,7 @@ features: - Clang 13 - MSVC 14.44 - Xcode 13.4.1 + content: lambda-omit-parens.md - desc: "Repairing input range adaptors and `std::counted_iterator`" paper: P2259 diff --git a/features_cpp26.yaml b/features_cpp26.yaml index 828a75e..2f50c59 100644 --- a/features_cpp26.yaml +++ b/features_cpp26.yaml @@ -34,6 +34,7 @@ features: - desc: "`constexpr` cast from `void*`: towards `constexpr` type-erasure" paper: P2738 + summary: "Recover a typed pointer from `void*` during constant evaluation." support: - GCC 14 - Clang 17 @@ -41,6 +42,7 @@ features: ftm: - name: __cpp_constexpr value: 202306L + content: constexpr-void-cast.md - desc: "On the ignorability of standard attributes" paper: P2552 @@ -1318,7 +1320,9 @@ features: - desc: "Annotations for Reflection" paper: P3394 + summary: "Attach compile-time values to declarations for reflection to read back." support: [GCC 16] + content: reflection-annotations.md - desc: "Splicing a base class subobject" paper: P3293