Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
CAN CSA ISO IEC TR 24731-1-12 (2016) is the Canadian adoption by the Standards Council of Canada (via CSA Group) of the international technical report ISO/IEC TR 24731-1:2012, titled Information technology — Programming languages, their environments and system software interfaces — Extensions to the C library — Part 1: Bounded-length strings. This document defines a set of alternative functions for the C standard library that accept explicit length limitations, thereby reducing the risk of buffer overflows and other memory safety issues common in C programming.
The report does not supersede the C standard (ISO/IEC 9899) but serves as a precursor to the optional Annex K (“Bounds-checking interfaces”) that appeared in the C11 standard. Therefore, it is of significant historical and practical importance for developers working in environments where robust string handling is critical, such as embedded systems, operating systems, and safety-critical applications.
Traditional C string functions (e.g., strcpy, strcat, sprintf) rely on the programmer to ensure that destination buffers are large enough to hold the result. This has led to countless buffer overflow vulnerabilities. The bounded-length functions add an explicit rsize_t parameter representing the size of the destination buffer, and they perform runtime constraint checks. If a constraint is violated (e.g., source string too long), the function invokes a runtime-constraint handler instead of continuing unsafely.
| Traditional Function | Bounded-Length Counterpart | Key Behaviour |
|---|---|---|
strcpy(dst, src) | strcpy_s(dst, dstsz, src) | Copies at most dstsz-1 characters; null-terminates |
strcat(dst, src) | strcat_s(dst, dstsz, src) | Appends, respecting destination size |
strncpy(dst, src, n) | strncpy_s(dst, dstsz, src, n) | More intuitive semantics; null-terminates even if n ≥ dstsz |
sprintf(buf, fmt, ...) | sprintf_s(buf, bufsz, fmt, ...) | Writes at most bufsz-1 characters; fails on truncated output |
vsprintf(buf, fmt, ap) | vsprintf_s(buf, bufsz, fmt, ap) | Same bounded behaviour with variable argument list |
gets(buf) | gets_s(buf, bufsz) | Reads at most bufsz-1 characters from stdin |
scanf(format, ...) | scanf_s(format, ...) | Requires size arguments for each %c, %s, %[ |
All functions operate with a new type rsize_t defined in <stdint.h> (or <cstdint> in C++), which is an unsigned integer type capable of holding the size of any object. Constraint violations (e.g., null pointers, zero or too-large sizes) cause the functions to return a non-zero error code and optionally call the system’s runtime-constraint handler.
While CAN CSA ISO IEC TR 24731-1-12 (2016) is a Technical Report rather than a normative standard, its functions were largely incorporated into the Annex K of the C11 standard (ISO/IEC 9899:2011). However, Annex K is optional and not universally implemented. The following table summarises support in common environments:
| Environment | Annex K / Bounded Function Support | Notes |
|---|---|---|
| Microsoft Visual C++ | Full (_s suffix functions) | Implements the functions even before C11; requires _CRT_SECURE_NO_WARNINGS or _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES for legacy compatibility |
| GCC / Clang (glibc) | Partial / opt-in | Provides __STDC_WANT_LIB_EXT1__ macro; not enabled by default; many functions are not implemented |
| Embedded / RTOS libraries | Varies | Often implement only a subset; runtime-constraint handler may be a custom callback |
| Standalone ISO C implementations | Optional per C11/K.3 | Only required if __STDC_LIB_EXT1__ is defined and the user defines __STDC_WANT_LIB_EXT1__ before inclusion |
To use the bounded-length functions in a standards-compliant manner, the application must:
__STDC_WANT_LIB_EXT1__ to 1 before including any standard headers.__STDC_LIB_EXT1__ is defined (indicating the implementation provides Annex K).As a CAN/CSA adoption, this document is a National Standard of Canada (NSC). It can be referenced in contracts, procurement specifications, and regulatory frameworks that require adherence to robust coding practices. While compliance is not mandatory in all contexts, it is increasingly expected in sectors such as:
The Technical Report formed the foundation for Annex K. However, the committee chose to make Annex K optional. Consequently, the _s functions are not universally available, and there has been debate within the C community about their usability. Nevertheless, adopting CAN CSA ISO IEC TR 24731-1-12 (2016) provides a well-documented, pragmatic approach to reducing buffer-overflow risks without requiring a complete rewrite of existing C code.
_s functions if I already use strncpy and snprintf?strncpy and snprintf. They also guarantee null-termination in more edge cases. If you already perform rigorous manual checks, the _s functions add an extra layer of safety but may require portability workarounds. __STDC_WANT_LIB_EXT1__ as 1, check for the presence of the macro __STDC_LIB_EXT1__. If it is defined, the implementation claims Annex K compliance. You can also attempt to call one of the functions (e.g., strcpy_s) and see if the code compiles and links. Document reference: CAN CSA ISO IEC TR 24731-1-12 (2016) | Category: ISO IEC TR | Year of publication: 2016 | Article prepared in 2026