Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: lite editing

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
bgColor#ffcccc
langc
#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
bgColor#ffcccc
langc
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
bgColor#ffcccc
langc
#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.

...