...
The ungetc()
function does not set the error indicator even when it fails, so it is not possible to check for errors reliably unless it is known that the argument is not equal to EOF
.
The C Standard 7.31.3.10 paragraph 3 [ISO/IEC 9899:20112024] states that "one
)ne wide character of pushback is guaranteed...
," so this should not be an issue if, at most, one character is ever pushed back before reading again. (See FIO13-C. Never push back anything other than one read character.)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h>
#include <string.h>
enum { SIG_DESC_SIZE = 32 };
typedef struct {
char sig_desc[SIG_DESC_SIZE];
} signal_info;
void func(size_t num_of_records, size_t temp_num,
const char *tmp2, size_t tmp2_size_bytes) {
signal_info *start = (signal_info *)calloc(num_of_records,
sizeof(signal_info));
if (tmp2 == NULL) {
/* Handle error */
} else if (temp_num > num_of_records || temp_num == 0) {
/* Handle error */
} else if (tmp2_size_bytes < SIG_DESC_SIZE) {
/* Handle error */
}
signal_info *point = start + temp_num - 1;
memcpy(point->sig_desc, tmp2, SIG_DESC_SIZE);
point->sig_desc[SIG_DESC_SIZE - 1] = '\0';
/* ... */
free(start);
} |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h>
#include <string.h>
enum { SIG_DESC_SIZE = 32 };
typedef struct {
char sig_desc[SIG_DESC_SIZE];
} signal_info;
void func(size_t num_of_records, size_t temp_num,
const char *tmp2, size_t tmp2_size_bytes) {
signal_info *start = (signal_info *)calloc(num_of_records,
sizeof(signal_info));
if (start == NULL) {
/* Handle allocation error */
} else if (tmp2 == NULL) {
/* Handle error */
} else if (temp_num > num_of_records || temp_num == 0) {
/* Handle error */
} else if (tmp2_size_bytes < SIG_DESC_SIZE) {
/* Handle error */
}
signal_info *point = start + temp_num - 1;
memcpy(point->sig_desc, tmp2, SIG_DESC_SIZE);
point->sig_desc[SIG_DESC_SIZE - 1] = '\0';
/* ... */
free(start);
} |
...
- that function cannot fail.
- its return value is inconsequential; that is, it does not indicate an error.
- it is one of a handful of functions whose return values are not traditionally checked.
These functions are listed in the following table:
Functions for which Return Values Need Not Be Checked
Function | Successful Return | Error Return |
---|---|---|
| Character written |
|
| Wide character written |
|
| Nonnegative |
|
| Nonnegative |
|
| Number of characters (nonnegative) | Negative |
| Number of wide characters (nonnegative) | Negative |
kill_dependency() | The input parameter | NA |
memcpy() , wmemcpy() | The destination input parameter | NA |
memmove() , wmemmove() | The destination input parameter | NA |
strcpy() , wcscpy() | The destination input parameter | NA |
strncpy() , wcsncpy() | The destination input parameter | NA |
strcat() , wcscat() | The destination input parameter | NA |
strncat() , wcsncat() | The destination input parameter | NA |
memset() , wmemset() | The destination input parameter | NA |
The return value of a call to fprintf()
or one of its variants (vfprintf()
, wfprintf()
, vwfprintf()
) or one of the file output functions fputc()
, fputwc()
, fputs()
, fputws()
may be ignored if the output is being directed to stdout
or stderr
. Otherwise, the return value must be checked.
If a function's return value is to be ignored, it is recommended that the function's results return value should be explicitly cast to to void to to signify the programmer's intent:
Code Block | ||||
---|---|---|---|---|
| ||||
int main() { (void) printffprintf(stdout, "Hello, world\n"); // printffprintf() return value safely ignored } |
...
[DHS 2006] | Handle All Errors Safely |
[Henricson 1997] | Recommendation 12.1, "Check for All Errors Reported from Functions" |
[ISO/IEC 9899:20112024] | Subclause 7.2131.73.10, "The ungetc Function" |
[VU#159523] |
...