2

I'm learning C++. The codes below confused me:

int test_return(int a)
{
    for (int i = 40; i < 44; i++)
    {
        if (i == a)
        {
            cout << "return here with i: " << i << endl;
            return 59;
        }
    }
}

int main()
{
    cout << "in main: " << test_return(61) << endl;
    return 0;
}

I know I'm missing a return statement at the end of function test_return.

But the compiler says no error and it works when executed.

So I pick up some particular numbers like 40,44,59,61 to see which one the function test_return will choose to return.

I tried several times, the output is always this:

in main: 44

It seems like that the function test_return returned the int i before the for-statement ended.

My question is:

Is this legal?

How does it work?

Update:

I add these codes at the end of function test_return:

int i = 100;
int square = i * i;

It comes out:

in main: 10000

Thanks for @Vlad from Moscow's answer! It helps.

Xun Chenlong
  • 1,622
  • 2
  • 11
  • 14
  • 10
    Undefined behavior see [Why does this C++ snippet compile (non-void function does not return a value)](http://stackoverflow.com/q/20614282/1708801) – Shafik Yaghmour Nov 06 '15 at 13:39
  • See this as well http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pr – Trevor Brown Nov 06 '15 at 13:45
  • It didn't return anything, but `main` looked in the place where the return value should have been stored and found 44. Just like you may get some result if you're doing math and happen to divide by zero, an undefined program may produce some result. – molbdnilo Nov 06 '15 at 13:45
  • 1
    Please compile with warnings turned on. – Emil Laine Nov 06 '15 at 14:29

2 Answers2

6

If there is an Intel-compatible computer then it seems the function returns the result in register EAX.

At the same time the function uses this register for variable i.

So after the loop the register always contains 44.

This value receives the caller.

Of course the function has undefined behaviour. It shall have an explicit return statement with an expression at the end of the function after the loop.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

But the compiler says no error and it works when executed.

This depends on your warning level.

For example, MSVC when compiled with anything from /W1 to /W4, says:

warning C4715: 'test_return' : not all control paths return a value

You can even turn the warning into an error with the /WX option:

error C2220: warning treated as error - no 'object' file generated
warning C4715: 'test_return' : not all control paths return a value

GCC or other compilers have similar options. Just read the documentation or research the options in Google.

The philosophy in C++ is that it is the developer's fault if they do not carefully consider their compiler settings, use low warning levels or ignore warnings. If you do any of those things, then the result will often be undefined behaviour at run-time, like in your case (a missing return value).

You should also know the C++ standard does not distinguish between errors and warnings; it knows only so-called "diagnostic messages". Whether the compiler should turn these into warnings or errors is not mandated anywhere. However, no such diagnostic message is required for a missing return value. The warning (or error) you receive for your code is therefore optional from the C++ standard point of view. That's OK, because compilers are free to provide more output, even in situations where no diagnostic message is required.

By the way...

it works when executed.

That's just a coincidence. Undefined behaviour means that everything can happen, including the desired behaviour every now and then.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62