You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|`fd_arg_write(`_`fd-index`_`)`| GCC 13.1.0 | Function | Mark writable file descriptors in positional arguments. |
41
41
|`noreturn`| GCC 2.5.0<br/>Clang 4.0.0 | Function | Mark functions that never return. |
42
42
|`tainted_args`| GCC 12.1.0 | Function or function pointer | Mark functions with arguments that require sanitization. |
43
+
|`counted_by(`_`variable`_`)`| GCC 15.1.0<br/>Clang 18.0.0 | Variable | Mark flexible array member or pointer in structure with _`variable`_ holding their element count. |
44
+
|`counted_by_or_null(`_`variable`_`)`| Clang 19.1.0 | Variable | As above, but pointer is either a null pointer or is pointing to memory of the specified count. |
45
+
|`sized_by(`_`variable`_`)`| Clang 20.1.0 | Variable | Mark flexible array member or pointer in structure with _`variable`_ holding their size in bytes. |
46
+
|`sized_by_or_null(`_`variable`_`)`| Clang 20.1.0 | Variable | As above, but pointer is either a null pointer or is pointing to memory of the specified size. |
[^gcc-tainted-args]: GCC team, [Using the GNU Compiler Collection (GCC): 6.35.1 Common Function Attributes: tainted_args](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-tainted_005fargs-function-attribute), GCC Manual, 2025-08-08.
437
441
[^Malcolm23]: Malcolm, David. [Enable "taint" state machine with -fanalyzer without requiring -fanalyzer-checker=taint](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103533#c9), GCC Bug 103533, 2023-12-01.
438
442
443
+
### Mark flexible array member or pointer in structure with variable holding their element count
444
+
445
+
| Attribute | Supported since | Type | Description |
|`counted_by(`_`variable`_`)`| GCC 15.1.0<br/>Clang 18.1.0 | Variable | Mark flexible array member or pointer in structure with _`variable`_ holding their element count. |
448
+
|`counted_by_or_null(`_`variable`_`)`| Clang 19.1.0 | Variable | As above, but pointer is either a null pointer or is pointing to memory of the specified count. |
449
+
|`sized_by(`_`variable`_`)`| Clang 19.1.0 | Variable | Mark flexible array member or pointer in structure with _`variable`_ holding their size in bytes. |
450
+
|`sized_by_or_null(`_`variable`_`)`| Clang 19.1.0 | Variable | As above, but pointer is either a null pointer or is pointing to memory of the specified size. |
451
+
452
+
The `counted_by` attribute associates a C99 flexible array member or pointer field in a structure with another field that specifies the number of elements it contains[^gcc-counted-by].
453
+
It improves compiler diagnostics and runtime checks (e.g., the `-fsanitize=bounds` array bound sanitizer and `__builtin_dynamic_object_size`).
454
+
The associated `variable` must be of integer type and must be declared before the annotated field. Negative values of `variable` are treated as zero.
455
+
456
+
The `counted_by` annotation cannot apply to pointers to incomplete types or types without size such as `void *`. However, `counted_by` is allowed for pointers to incomplete (non-void) struct/union types if they can be completed before first use.
457
+
For incomplete types and `void *` Clang provides a `sized_by` annotation[^clang-counted-by] which can be used to associate the field to a `variable` holding their size in bytes.
458
+
459
+
Neither `counted_by` nor `sized_by` is allowed for function pointers or for pointers to structs/unions with flexible array members.
460
+
461
+
Clang's `counted_by_or_null` and `sized_by_or_null` variants accounts for cases where an annotated pointer is either a null pointer or is pointing to memory of the specified count/size.
462
+
If the pointer is null the size is effectively 0.
463
+
Accessing such a pointer with these bounds annotations will require a null check to avoid a null pointer dereference.
464
+
465
+
### Example usage
466
+
467
+
In C23 attribute syntax:
468
+
469
+
~~~c
470
+
struct P {
471
+
size_t count;
472
+
char array[][[clang::counted_by(count)]];
473
+
};
474
+
475
+
struct P *p = malloc(sizeofstruct P);
476
+
~~~
477
+
478
+
In `__attribute__` keyword syntax:
479
+
480
+
~~~c
481
+
struct P {
482
+
size_t count;
483
+
char array[]__attribute__((counted_by(count)));
484
+
};
485
+
486
+
struct P *p = malloc(sizeofstruct P);
487
+
~~~
488
+
489
+
The use of `counted_by` or `sized_by` establishes a relationship between the annotated field `array` and `count` field in the same structure. The user is responsible to ensuring the following invariants hold for`array` and `count`:
490
+
491
+
-`p->count` must be initialized before first use of `p->array`
492
+
-`p->array` must always have at least `p->count elements`
493
+
- if `p->array` is a pointer, both `p->array` and `p->count` must be updated together (e.g., by replacing the whole structure).
494
+
495
+
For existing code where `counted_by` nor `sized_by` cannot be used without re-ordering struct field declarations, which may not be feasible since it would break application binary interface (ABI) compatibility, Clang enables late parsing of these attributes with the `-fexperimental-late-parse-attributes` flag[^clang-19.1.0], enabling usage in code such as the below example:
496
+
497
+
~~~c
498
+
struct Buffer {
499
+
/* Refering to `count` requires late parsing */
500
+
char* buffer [[clang::counted_by(count)]];
501
+
/* Swapping `buffer` and `count` to avoid late parsing would break ABI */
502
+
size_t count;
503
+
};
504
+
~~~
505
+
506
+
[^gcc-counted-by]: GCC team, [Using the GNU Compiler Collection (GCC): 6.4.2.1 Common Variable Attributes: counted_by](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-counted_005fby-variable-attribute), GCC Manual, 2025-08-08.
0 commit comments