7.1.0 General
The Ocean Edition I library is the ISO C99 library with its behavior normalized in the same way and for the same reasons the language was normalized.
The library follows the language's principles:
- where traditional behavior is already sensible, it is preserved,
- where several interfaces differ only because of historical constraints, their behavior is normalized as far as compatibility permits,
- where an operation can fail, the failure contract is defined,
- where overlap can be handled safely without changing the programmer's conceptual operation, overlap is safe,
- where object sizes are available, checked variants are exposed without changing ordinary C syntax.
See behavior.md section 111.
Interface declarations appear in headers. A header may be included more than once, in any order, with the same effect as including it once.
7.1.1 Definitions of Terms
decimal point character
The character used to separate the integer part of a number from its fractional part in the current locale.
null pointer
A pointer value that designates no object and no function. It is written with a null constant, spelled null or NULL, which are keywords under clause 6.4.1.2 rather than macros this library supplies. See clause 6.3.2.3 and clause 6.4.4.6.
null-terminated string
A contiguous sequence of characters terminated by, and including, the first null character. A pointer to a string points to its initial character. The length of a string is the number of characters preceding its null character.
reentrant variant
A library function that writes its result into storage the caller supplies, rather than into an object the library owns. Where this specification requires one, it fixes the name, which is the base name followed by _r.
valid string argument
A pointer to a null-terminated string, all of whose bytes through the terminator lie within a single valid object. Passing anything else where a valid string argument is required is unsafe memory behavior.
object size argument
A count of bytes or of elements that shall not exceed the size of the object the accompanying pointer designates.
7.1.2 The Library and the Global Namespace
Every entity of the standard library is a member of the global namespace, under clause 6.9.6.2.
A program therefore reaches the library by an unqualified name from anywhere, including from inside a namespace, because unqualified lookup reaches the global namespace under clause 6.5.1.3:
namespace net
{
int open(const char *host)
{
return socket(AF_INET, SOCK_STREAM, 0);
}
}
Where a namespace declares a member with the same name as a library entity, the library entity is named with a leading :::
namespace net
{
int close(int handle);
int shutdown(int handle)
{
return ::close(handle); /* the library one */
}
}
No standard header contains a #namespace directive, and no future revision of this specification will add one, since doing so would rename every entity of the library.
Standard identifiers and consecutive underscores. No identifier this specification requires the library to declare contains two consecutive underscores, so no library name collides with the linkage name of a namespaced entity under clause 6.9.6.4. An implementation shall observe the same restriction for the identifiers it adds, or shall document the names it uses that do not.
7.1.3 Standard Headers
The standard headers are listed in clause 7.2. Each is included by the familiar spelling:
#include <stddef.h>
A standard header may be included in any order and any number of times.
A program shall not include a standard header inside an external declaration or definition, and shall not include one while a macro is defined with the same name as an identifier the header declares.
If a program defines a macro with the same name as a library function and then includes the header, the macro definition governs. A program can force the function to be used by parenthesizing the name:
size_t n = (strlen)(&text[0]);
7.1.4 Reserved Identifiers
Each header declares or defines the identifiers listed in its clause, and reserves them.
In addition, the following are always reserved to the implementation, and clause 6.4.2.1 states the general rule:
- every identifier beginning with an underscore followed by an uppercase letter or by another underscore,
- every identifier beginning with an underscore at file scope,
- every external identifier the standard library declares,
- every macro name a standard header defines, while its header is included,
- names beginning with
Efollowed by a digit or an uppercase letter, reserved for<errno.h>, - names beginning with
is,to,str,mem, orwcsfollowed by a lowercase letter, reserved for future library use in the corresponding headers, - names beginning with
LC_followed by an uppercase letter, reserved for<locale.h>, - names beginning with
SIGorSIG_followed by an uppercase letter, reserved for<signal.h>, - names ending in
_t, reserved for type names, - names ending in
_MAX,_MIN, or_WIDTHfollowing a type name, reserved for limit macros.
A program that declares a reserved identifier has behavior this specification does not define. An implementation should diagnose it.
7.1.5 Freestanding Headers
A freestanding implementation shall provide at least these headers:
<float.h>
<iso646.h>
<limits.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
They contain no function that requires an operating system, and every one of them is needed to write ordinary declarations.
<stdbool.h> remains in the list for source compatibility only. bool, true, and false are keywords under clause 6.4.1.3, so a freestanding program needs no header to use them. The same applies to null and NULL under clause 6.4.1.2, which no header defines.
A freestanding implementation may provide any other header, in whole or in part, and shall document what it provides.
7.1.6 Use of Library Functions
Every library function is declared with a complete prototype in its header, under clause 6.7.5.3. A program shall include the header rather than declaring a library function itself, because the declaration the header provides may involve implementation-specific qualifiers or macros.
A library function may be additionally implemented as a macro, provided the macro expands to an expression that evaluates each of its arguments exactly once and is fully protected by parentheses. This restriction is stricter than the ISO C99 rule, and it exists because a macro that evaluates an argument twice is a defect no caller can see.
Unless a clause says otherwise:
- a library function shall not modify an object through a pointer to
const, - a library function shall not retain a pointer its caller supplied after the call returns,
- a library function may be called from a signal handler only where clause 7.2.14 permits it,
- passing an invalid pointer, an invalid size, or an invalid string to a library function is unsafe memory behavior.
7.1.7 Library Conventions Specific to This Edition
7.1.7.1 Arrays at call sites
Because arrays do not convert to pointers, a call that passes an array writes the element pointer:
char buffer[64];
size_t used = strlen(&buffer[0]);
memset(&buffer[0], 0, sizeof(buffer));
A string literal argument is converted under clause 6.3.2.4, so ordinary calls with literals are written as always:
printf("count: %d\n", count);
fputs("done\n", stdout);
This is the most visible day-to-day difference between Ocean Edition I and traditional C, and it is mechanical. See annex-h-migration-and-interoperation.md.
7.1.7.2 Function pointers at call sites
Passing a function to a library function that takes a function pointer writes the address explicitly:
qsort(&items[0], count, sizeof(items[0]), &compare_item);
7.1.7.3 Overlap
Where a library function copies or moves bytes and the operation has a sensible overlap-safe meaning, the function is overlap-safe. The result is as though every source byte were read before any destination byte were written.
This applies to memcpy, strcpy, strncpy, strcat, strncat, and their wide-character counterparts. memmove remains available and is identical to memcpy.
Difference: ISO C99 makes overlapping memcpy undefined and provides memmove for the safe case. Modern implementations can provide the safe behavior at little or no cost, so the distinction buys nothing but defects. See behavior.md section 80.
7.1.7.4 Failure contracts
Every library function that can fail has a defined failure result, stated in its clause. A library function shall not produce an indeterminate value, and shall not leave an output object in an unspecified state.
Where a function fails partway through writing an output object, its clause states what the object contains on failure.
7.1.7.5 Errors that trap
A library function whose arguments make its operation impossible causes a defined trap where the impossibility is detectable and no error return is specified. Examples are a negative size where a size is required and a null pointer where the clause requires a valid object pointer.
A library function shall not silently produce a value in a case its clause does not define.
7.1.7.6 Checked variants
An implementation should provide checked variants of the library functions that take an object size, exposed under the checked profile of clause 4.6.4 or through a documented header.
A checked variant has the same name, the same signature, and the same defined behavior, and converts an out-of-range access into a defined trap instead of unsafe memory behavior. Programs shall not need to change their source to use them.
7.1.8 Errors and errno
errno is a modifiable lvalue of type int, declared in <errno.h>. It is not necessarily an object, and a program shall not take its address expecting a stable location. In an implementation providing threads, errno is per-thread.
errno is zero at program startup.
A library function may set errno to a nonzero value whether or not it fails, unless its clause says otherwise. A program that wants to detect an error through errno shall set errno to zero before the call and inspect it only after the call reports failure by its documented means.
An implementation shall not set errno to zero as a side effect of a successful call, because a program that relies on that is impossible to write portably.
The macros EDOM, ERANGE, and EILSEQ are defined by <errno.h>. An implementation may define more.
7.1.9 Limits and Numerical Values
<limits.h> and <float.h> describe the target's numerical properties, and their values shall agree with the data model of clause 5.2.4.2 and with the representation rules of clause 6.2.6.
Because integers are two's complement with no padding bits, the signed limit macros of a type of width N are exactly -2^(N-1) and 2^(N-1) - 1, and CHAR_BIT is 8.
7.1.10 Library Behavior That Is Not Defined
The library retains unsafe memory behavior wherever a caller can pass a pointer the implementation cannot validate. This is deliberate and follows Law 8. Ocean Edition I does not confuse danger with ambiguity, and the library is where most real danger lives.
What the library does not retain is arbitrary undefined behavior in cases where a deterministic result or a trap can reasonably be specified. Where an ISO C99 library clause says the behavior is undefined and the operation has an obvious correct answer, this edition specifies the answer.