3

When I try to compile my code, I get an error message that says "control may reach end of non void function." What does this message mean and how can I avoid this error?

Here is the function that's causing the error:

bool myfunction(int board[], int r, int c)
{
    if (r > 0)
    {
        if (board[r - 1][c] == 0)
        {
            return true;
        }
    }
    else if (c > 0)
    {
        if (board[r][c - 1] == 0)
        {
            return true;
        }
    }
    else
    {
        return false;
    }
}
  • It's a bit confusing that you say the error occurs when you run the code, as the error you describe is usually produced at compile time, and not at run time. Also, I don't think that error relates to the code shown here. The final else should resolve any left over conditions. Perhaps try removing the final else, and just return false, to see if that resolves the problem. – Luke Van In Aug 24 '14 at 0:15
26

This problem comes from a misunderstanding of the flow of control in your algorithm. Here's a representation of that control flow in pseudocode:

if (outer-condition-1)
    if (inner-condition-1)
        return 1
else if (outer-condition-2)
    if (inner-condition-2)
        return -1
else
    return 0

If you translate this into a flow chart, you will see why the compiler is yelling at you:

Flow chart

An else block is only ever related to one if...elseif...else construct at a time, so the last else block is attached only to the outer if conditions and not to the inner if conditions. If an outer condition evaluates to true and its inner condition evaluates to false, the else block will not be executed at all. This means the function will never encounter an explicit return statement, which is what the compiler doesn't like; every function must always return something, no matter what input it receives.

There are a few ways to fix this. The most direct solution is to add a return statement at the end of the function, outside of the conditional statements, but that's a bit sloppy—it can hide problems that would otherwise throw errors, making it a bit harder to find bugs.

Another way is to flatten your nested conditions, so that the pseudocode looks like this:

if (outer-condition-1 and inner-condition-1)
    return 1
else if (outer-condition-2 and inner-condition-2)
    return -1
else
    return 0

That might be appropriate if you're sure your program is working as intended with the current setup. But if you need something unique to happen when an outer condition is satisfied and an inner condition is not satisfied, you need to keep the nested structure but deal directly with every possible outcome:

if (outer-condition-1)
    if (inner-condition-1)
        return 1
    else
        return 2
else if (outer-condition-2)
    if (inner-condition-2)
        return -1
    else
        return -2
else
    return 0

In either case, once the program reaches the first if statement, every path available to it will result in an explicit return statement, thus avoiding the control my reach end of non-void function message from Clang.

A related concept is "single entry, single exit" (SESE), which would demand that your function return a value only once at the end, rather than using the "early return" statements inside the conditional logic. This usually means defining an extra variable to hold the value that will be returned; for example:

declare int r
if (condition-1)
    r = 1
else if (condition-2)
    r = -1
else
    r = 0
return r

For those interested in a more detailed examination of the SESE concept, you can find a huge amount of discussion online and in programming texts; I like this question on programmers.SE, which contains a variety of stylistic and historical perspectives in its answers.

| improve this answer | |
  • 1
    this could be saved as the model-to-perfect-answer ;) – abelinux Dec 29 '14 at 15:59
  • Since it's now a dupe target and the OP is long gone, I took the liberty of revising both the question and the answer so we have a canonical resource for this particular topic. – Air Dec 29 '14 at 17:41
  • Great explanation – sqrcompass Jul 31 '16 at 15:57
  • Yes, thank you for constructing a flow chart. A picture's worth 1000 words an' all that. Helped me immensely. – Lindsey Oct 5 '17 at 19:34
0

The error means that the function might return nothing. You should add some return xxx or more else if and else's after

if (board[r][c - 1] == 0)
{
    return true;
}

and

if (board[r][c - 1] == 0)
{
    return true;
}

, because the contents of the if (r > 0) and else if (c > 0) conditions might not return at all. Another way is to use if ((r > 0) & (board[r - 1][c] == 0)) and else if ((c > 0) & (board[r][c - 1] == 0)) instead of two conditions.

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .