If control reaches the closing curly brace (}
) of a nonvoid non-void function without evaluating a return
statement, using the return value of the function call causes undefined behavior. See undefined behavior 88 in Annex J of the C Standard. This rule is related to MSC01-C. Strive for logical completeness because both practices guideilnes are intended to ensure that programs properly handle all possible conditions.
...
In this noncompliant code example, control reaches the end of the checkpass()
function when the two strings passed to strcmp()
are not equal. This event leads to , resulting in undefined behavior, and various . Many compilers will generate code equivalent to for the checkpass()
function, returning various values when along the execution path where no return
statement is executed in checkpass()
defined.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <string.h> int checkpass(const char *password) { if (strcmp(password, "pass") == 0) { return 1; } } void func(const char *userinput) { if (checkpass(userinput)) { printf("Success\n"); } } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
size_t getlen(const int *input, size_t maxlen, int delim) { for (size_t i = 0; i < maxlen; ++i) { if (input[i] == delim) { return i; } } } void func(int userdata) { size_t i; int data[] = { 1, 1, 1 }; i = getlen(data, sizeof(data), 0); data[i] = userdata; } |
...
Code Block |
---|
example.c: In function 'getlen': example.c:12: warning: control reaches end of non-void function |
When the program was is compiled and run with GCC 4.4.3 on Linux, the getlen()
function returned 5, causing an out-of-bounds write to the data
array:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> size_t getlen(const int *input, size_t maxlen, int delim) { for (size_t i = 0; i < maxlen; ++i) { if (input[i] == delim) { return i; } } } int main(int argc, char **argv) { size_t i; int data[] = { 1, 1, 1 }; i = getlen(data, sizeof(data), 0); printf("Returned: %zu\n", i); data[i] = 0; return 0; } |
...
MSC37-EX1: According to the C Standard, subclause 5.1.2.2.3, paragraph 1 [ISO/IEC 9899:2011], "reaching the }
that terminates the main function returns a value of 0." ThusAs a result, it is permissible for control to reach the end of the main function without executing a return statement.
...
Using the return value from a nonvoid non-void function where control reaches the end of the function can lead to a buffer overflow vulnerability as well as other unexpected program behaviors.
...