Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions content/atomic-floating-min-max.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
4 changes: 0 additions & 4 deletions content/auto.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
---
execute: true
---

## What It Does

The `auto` keyword specifies that a variable's type is deduced from its initializer.
Expand Down
4 changes: 0 additions & 4 deletions content/bit-cast.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
---
execute: true
---

## What It Does

`std::bit_cast()` reinterprets the object representation of one type as another type.
Expand Down
6 changes: 0 additions & 6 deletions content/c-alignas-alignof.md
Original file line number Diff line number Diff line change
@@ -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)`
Expand Down
6 changes: 0 additions & 6 deletions content/c-anonymous-struct-union.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
38 changes: 38 additions & 0 deletions content/c-array-parameter-qualifiers.md
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>

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;
}
```
6 changes: 0 additions & 6 deletions content/c-atomic.md
Original file line number Diff line number Diff line change
@@ -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 `<stdatomic.h>`
Expand Down
5 changes: 0 additions & 5 deletions content/c-attributes.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
---
execute: true
show_assembly: true
---

## What It Does

C23 introduces standard attributes using the `[[attribute]]` syntax. Standard attributes
Expand Down
5 changes: 0 additions & 5 deletions content/c-auto.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-binary-literals.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-bitint.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-bool-true-false.md
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
34 changes: 34 additions & 0 deletions content/c-cmplx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## What It Does

`CMPLX(x, y)` is a function-like macro in `<complex.h>` 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 <complex.h>
#include <math.h>
#include <stdio.h>

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;
}
```
6 changes: 0 additions & 6 deletions content/c-compound-literals.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-constexpr.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 0 additions & 6 deletions content/c-designated-init.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-digit-separators.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
---
execute: true
show_assembly: true
---

## What It Does

Single quote characters (`'`) can appear within integer and floating-point constants to
Expand Down
5 changes: 0 additions & 5 deletions content/c-elifdef.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
---
execute: true
show_assembly: true
---

## What It Does

`#elifdef` and `#elifndef` are preprocessor directives that combine `#elif` with `#ifdef`
Expand Down
4 changes: 0 additions & 4 deletions content/c-embed.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 0 additions & 5 deletions content/c-empty-init.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
---
execute: true
show_assembly: true
---

## What It Does

Empty initializers `{}` zero-initialize an object. For structures and arrays, all members
Expand Down
32 changes: 32 additions & 0 deletions content/c-enum-trailing-comma.md
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>

enum color
{
RED,
GREEN,
BLUE,
};

int main(void)
{
enum color c = BLUE;
printf("BLUE = %d\n", c);
printf("count = %d\n", BLUE + 1);
}
```
46 changes: 46 additions & 0 deletions content/c-fenv.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## What It Does

`<fenv.h>` 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 <fenv.h>
#include <math.h>
#include <stdio.h>

#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));
}
```
5 changes: 0 additions & 5 deletions content/c-fixed-enum.md
Original file line number Diff line number Diff line change
@@ -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 { ... }`.
Expand Down
6 changes: 0 additions & 6 deletions content/c-flexible-array.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
43 changes: 43 additions & 0 deletions content/c-fopen-exclusive.md
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>

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;
}
```
Loading
Loading