If control reaches the end of a non-void function, using the return value of the function call results in undefined behavior. See also undefined behavior 7 of Appendix J.
This rule is related to MSC01-C. Strive for logical completeness.
Noncompliant Code Example
In this noncompliant code example, control reaches the end of the checkpass()
function when the two strings passed to strcmp()
are not equal. This leads to undefined behavior, and various compilers generate code equivalent to the checkpass function returning various values when no return checkpass()
is reached.
int checkpass(char *password) { if (strcmp(password, "pass") == 0) { return 1; } } /* ... */ if (checkpass(userinput)) { printf("Success\n"); }
This error is frequently diagnosed by compilers (see MSC00-C. Compile cleanly at high warning levels).
Compliant Solution
This compliant solution ensures that control never reaches the end of the checkpass function.
int checkpass(char *password) { if (strcmp(password, "pass") == 0) { return 1; } return 0; } /* ... */ if (checkpass(userinput)) { printf("Success!\n"); }
Noncompliant Code Example
In this noncomplaint code example, control reaches the end of the the getlen()
function when input
does not contain the integer delim
. As the potentially undefined return value of getlen is later used as an index into an array, this can lead to a buffer overflow.
size_t getlen(int *input, size_t maxlen, int delim) { size_t i; for (i = 0; i < maxlen; ++i) { if (input[i] == delim) { return i; } } } /* ... */ size_t i; int data[] = {1, 1, 1}; i = getlen(data, sizeof(data), 0); data[i] = userdata;
Noncompliant Code Example
This compliant solution handles the unexpected situation by immediately terminating the program. The correct method for handling this type of error is specific to the application and the type of error (see ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy for more on error handling).
size_t getlen(int *input, size_t maxlen, int delim) { size_t i; for (i = 0; i < maxlen; ++i) { if (input[i] == delim) { return i; } } /* The panic function reports the error and terminates the program. */ panic("Fatal error: Invalid input!\n"); } /* ... */ size_t i; int data[] = {1, 1, 1}; i = getlen(data, sizeof(data), 0); data[i] = userdata;
Implementation Details
When a program containing this noncompliant code example is compiled with -Wall
on most versions of the GCC compiler,
size_t getlen(int *input, size_t maxlen, int delim) { size_t i; for (i = 0; i < maxlen; ++i) { if (input[i] == delim) { return i; } } }
the following warning is generated
example.c: In function âgetlenâ: example.c:12: warning: control reaches end of non-void function
Risk Assessment
Using the return value from a non-void function where control reaches the end of the function can lead to unexpected program behavior, and possibly abnormal program termination.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC37-C |
high |
unlikely |
low |
P9 |
L2 |
References
[[ISO/IEC 9899:1999]] Section 6.9.1, "Function definitions"