All library subroutines where an error may occur usually have an optional integer pointer argument. If the latter is given and an error occurs the error code will be written into the integer at the pointer’s location. If no error occurs the integer will not be changed. As such this allows by design a logical-OR behavior in which one may call several subroutines and check at the very end whether an error code has been set.
This error code is also set into a thread-local variable and can be inquired using the 3.1.3 function for the current thread. The latter will also provide the name of the offending function for easier traceback.
Functions that are designed for specific purposes may however return NaN (Not-a-Number) or infinity . The specific error behavior for those is documented for each of such functions individually.