Returning from functions (Lecture 17)

@ben What are your thoughts on multiple returns vs. enforcing a single return from a function?

Does one style produce a better compiled application than the other:

Style 1:

int foo ( int p1 )
{
int result = 0;
    if (p1 < 1)
    {
        return result;
    }

    if(p1 > 0 && p1 < 32)
    {  
        result = 1;
    }

    if(p1 > 31 && p1 < 127)
    {  
        result = 2;
    }

    if(p1 > 126)
    {  
        result = 3;
    }

    return result;
}

or

Style 2:

int foo ( int p1 )
{
    
    if (p1 < 1)
    {
        return 0;
    }

    if(p1 > 0 && p1 < 32)
    {  
        return 1;
    }

    if(p1 > 31 && p1 < 127)
    {  
        return 2;
    }

    if(p1 > 126)
    {  
        return 3;
    }


}

Thanks

I think you may as well return immediately because it’s easier to reason about (no need to look further down to see if result is changed again). Also the compiled code will also return at this point

Doesn’t that add a bunch of added return code in the assembled application? Wouldn’t that produce inefficient executables? The size of your app would be slightly larger if done everywhere as a ‘pattern’.

Also, it might be messy to read and update. What if you had to update a large function and missed one place that returned from it, thus you might spend hours trying to debug?

It would be great if other Unreal students would chirp-in here, as it could be a great discussion.

I don’t bite! Not very hard at any rate… If you’re new to development, what’s your ‘gut feeling’ about this? If you’re experienced, then what’s worked for you, or your team?

Compilers are smart and they would most likely optimise any of those problems away. Now I don’t understand assembly but I enabled the assembler output file flag and diff’ed the logs, the diff on the debug version of the output log from Style 1 to Style 2 had 60 removals and 52 additions, 10 of which were just line number changes so 50 to 42. The release version had 2 removals and 2 additons, both of which were line number differences, so absolutely no differences.

So I guess in conclusion, don’t really worry about the assembler code and make your decision based on other metrics.

Also you can turn on this output log in Visual Studio by Project > Properties > C/C++ > Output Files > Assembler Output

1 Like

So I think that leaves us with the readability side to the argument. On the one hand, returning early, especially with error handling at the beginning of the function removes the need to indent everything within an else. Less indentation is usually good.

The counter to this is that it’s easy to miss a return statement as so you might not realise that the code has already been error checked and that you can assume the property to be true.

I think generally the first reason is stronger unless you are wrapping the error checking and control flow modification inside a macro. That happened in a company I worked for. That did NOT lead to better code :stuck_out_tongue:

I agree with Sam, less nested indentation is more readable. Also I think if you’re debugging using the proper tools it’s relatively easy to see where the execution control is returning.

1 Like

Privacy & Terms