errno is a modifiable error indicator provided by the C library. Functions may use it to communicate failure, while perror uses its current state to produce a diagnostic. Check a function's documented return value first; consult errno when that failure strategy requires it. section 8.1.3 section 15.5
Check the return value, then diagnose
if (puts("hello world") == EOF) { perror("can't output to terminal:"); exit(EXIT_FAILURE); } Here, EOF detects puts failure and perror adds a diagnostic based on errno. Do not ignore a library failure merely because execution can continue. section 8.1.3
Use errno carefully when a recoverable failure changes execution state:
- Save errno on entry when a function must preserve the surrounding execution state. section 15.6
- Restore the saved value during cleanup after an error, rather than exposing an incidental change. section 15.6
- Reset errno when a recovery path has handled the failure and continuing execution would otherwise leave stale error state. section 8.1.3
- Use platform-provided error macros from <errno.h>, recognizing that only some error values are imposed by the C standard. section 15.6
Table 8.2 Error return strategies for C library functions. Some functions may also indicate a specific error condition through the value of the errno macro.
| Failure return | Test | Typical case | Example |
| Null pointer | !value |
Other values are valid | fopen |
| Special error code | value == code |
Other values are valid | puts, clock, mktime, strtod, fclose |
| Nonzero value | value |
Value otherwise unneeded | fgetpos, fsetpos |
| Special success code | value != code |
Case distinction for failure condition | thrd_create |
| Negative value | value < 0 |
Positive value is a counter | printf |
Compare library failure conventions before deciding whether to test a return value, inspect errno, or apply both checks. section 8.1.3


