Safer C Library
From Open Watcom
The "Safer C Library" is the first major enhancement of the standard C library in many, many years. Its primary goal is to provide a set of "safe" functions with bounds checking and parameter validation. A secondary objective is to provide re-entrant (and therefore, thread-safe) replacements for poorly designed standard C library functions that use static buffers.
Strictly speaking, the Safer C Library offers little new functionality. Almost everything the extension does can be already achieved through other means. However, the new functions offer a consistent set of interfaces redesigned for safer use. It is expected that many users will wish to modify existing code to use the new functions.
The Safer C Library functions significantly reduce (but don't completely eliminate) the incidence of undefined behaviour. An important new concept is that of runtime-constraints. These constraints place requirements on arguments passed to the new functions; for instance, passing a null pointer argument is in most cases considered a runtime-constraint violation. If such violation occurs, a constraint handler will be called. The library provides several pre-made handlers, and users can register their own handler.
Proper use of the extension should to a large extent eliminate the danger of buffer overflows related to library calls. It should also lead to cleaner and more maintainable user code, because many checks that programmers (not the sloppy ones, obviously!) had to previously perform themselves are now encapsulated in library code.
The extension was delivered in Open Watcom version 1.5.
TR 24731 Tests
While implementing Safer C support, we have developed a non-exhaustive but fairly extensive set of tests for the new functions. We have made these tests available under the MIT license for general use. The archive may be downloaded here.
Implementation status for functions
| Function | Header | Implemented | Documented | Test written |
| tmpfile_s | stdio.h | yes | yes | yes |
| tmpnam_s | stdio.h | yes | yes | yes |
| fopen_s | stdio.h | yes | yes | yes |
| freopen_s | stdio.h | yes | yes | yes |
| fprintf_s | stdio.h | yes | yes | yes |
| fscanf_s | stdio.h | yes | yes | yes |
| printf_s | stdio.h | yes | yes | yes |
| scanf_s | stdio.h | yes | yes | yes |
| snprintf_s | stdio.h | yes | yes | yes |
| sprintf_s | stdio.h | yes | yes | yes |
| sscanf_s | stdio.h | yes | yes | yes |
| vprintf_s | stdio.h | yes | yes | yes |
| vfscanf_s | stdio.h | yes | yes | yes |
| vprintf_s | stdio.h | yes | yes | yes |
| vscanf_s | stdio.h | yes | yes | yes |
| vsnprintf_s | stdio.h | yes | yes | yes |
| vsprintf_s | stdio.h | yes | yes | yes |
| vsscanf_s | stdio.h | yes | yes | yes |
| get_s | stdio.h | yes | yes | yes |
| set_constraint_handler_s | stdlib.h | yes | yes | yes |
| abort_handler_s | stdlib.h | yes | yes | yes |
| ignore_handler_s | stdlib.h | yes | yes | yes |
| getenv_s | stdlib.h | yes | yes | yes |
| bsearch_s | stdlib.h | yes | yes | yes |
| qsort_s | stdlib.h | yes | yes | yes |
| wctomb_s | stdlib.h | yes | yes | yes |
| mbstowcs_s | stdlib.h | yes | yes | yes |
| wcstombs_s | stdlib.h | yes | yes | yes |
| memcpy_s | string.h | yes | yes | yes |
| memmove_s | string.h | yes | yes | yes |
| strcpy_s | string.h | yes | yes | yes |
| strncpy_s | string.h | yes | yes | yes |
| strcat_s | string.h | yes | yes | yes |
| strncat_s | string.h | yes | yes | yes |
| strtok_s | string.h | yes | yes | yes |
| strerror_s | string.h | yes | yes | yes |
| strerrorlen_s | string.h | yes | yes | yes |
| strnlen_s | string.h | yes | yes | yes |
| asctime_s | time.h | yes | yes | yes |
| ctime_s | time.h | yes | yes | yes |
| gmtime_s | time.h | yes | yes | yes |
| localtime_s | time.h | yes | yes | yes |
| fwprintf_s | wchar.h | yes | yes | yes |
| fwscanf_s | wchar.h | yes | yes | yes |
| snwprintf_s | wchar.h | yes | yes | yes |
| swprintf_s | wchar.h | yes | yes | yes |
| swscanf_s | wchar.h | yes | yes | yes |
| vfwprintf_s | wchar.h | yes | yes | yes |
| vfwscanf_s | wchar.h | yes | yes | yes |
| vsnwprintf_s | wchar.h | yes | yes | yes |
| vswprintf_s | wchar.h | yes | yes | yes |
| vswscanf_s | wchar.h | yes | yes | yes |
| vwprintf_s | wchar.h | yes | yes | yes |
| vwscanf_s | wchar.h | yes | yes | yes |
| wprintf_s | wchar.h | yes | yes | yes |
| wscanf_s | wchar.h | yes | yes | yes |
| wcscpy_s | wchar.h | yes | yes | yes |
| wcsncpy_s | wchar.h | yes | yes | yes |
| wmemcpy_s | wchar.h | yes | yes | yes |
| wmemmove_s | wchar.h | yes | yes | yes |
| wcscat_s | wchar.h | yes | yes | yes |
| wcsncat_s | wchar.h | yes | yes | yes |
| wcstok_s | wchar.h | yes | yes | yes |
| wcsnlen_s | wchar.h | yes | yes | yes |
| wcrtomb_s | wchar.h | yes | yes | yes |
| mbsrtowcs_s | wchar.h | yes | yes | yes |
| wcsrtombs_s | wchar.h | yes | yes | yes |
Other items
The __STDC_LIB_EXT1__ macro is predefined by the C compiler to 200509L to indicate TR 24731 support. This macro can be queried whether the support is available. To use the Safer C functions, #define __STDC_WANT_LIB_EXT1__ 1 before including standard header.

