Search code examples
cstringreturn

function does not end in a return statement


I am new to C but I know the fundamentals of coding. However, I cannot see why the compiler returns the error:

function ".." does not end in a return statement !

Here is my code:

string same_start_end(string s)

{
  char first_letter = string_charat(s, 0);
  string empty = "";
  if( string_length(s) <= 1)
  {
      return s;
  }
  else if (string_length(s) > 1)
  {
      for (int  i = 0; i < string_length(s); i++)
      {
          if( (string_charat(s, i) == first_letter) && (i != 0))
          {
              return string_sub(s, 0,i);
          }
      }
  }

}

Solution

  • The compiler warns that control may reach the end of your non-void function because control may reach the end of your non-void function.

    To prevent this you must do one of:

    • Disable the compiler warning. (With Clang, the command-line option -Wno-return-type does this.) (In C, it is allowed for a non-void function to flow off the end of the function without returning a value provided the caller does not attempt to use the return value.)
    • Make it apparent to the compiler that function returns.

    There are two paths where it is not clear to the compiler that the function returns.

    First, consider:

    if (string_length(s) <= 1)
       …
    else if (string_length(s) > 1)
    

    Mathematically, we know that either x ≤ 1 or x > 1, so “x ≤ 1 or x > 1” is true. However, the compiler does not know that the first call to string_length(s) returns the same value as the second call. So it cannot know that at least one of these conditions is true. It must assume they could both be false, and then control would flow to the end of the function without a return statement.

    Some compilers have a feature that allows you to declare a function to be pure, which would tell the compiler that it returns the same value given the same input and also does not change the program’s state in other ways. If you used that feature, or the compiler could see the definition of string_length, it might be able to detect that one of the two conditions is true. However, an easier way to fix this is simply to change else if (string_length(s) > 1) to else. Then the compiler knows that if the if clause is not executed, the else clause must be.

    Second, consider:

    for (int  i=0; i<string_length(s);i++)
        {
          if( (string_charat(s,i)==first_letter) && (i!=0))
            {
              return string_sub(s, 0,i);
            }
        }
    

    This loop can end without the if being triggered. There might be no character in s that equals the first character, and so the return is never executed. Then loop completes and control flows to the end of the function without a return statement.

    To prevent this, you could insert a return statement after the for loop. It would return whatever value you want to return when a match is not found.