cubix
cubix

Reputation: 19

c++ code behaves abnormally when the return value is missing

GCC 9.2.1 gives a warning that there is "no return statement in function returning non-void", however, the code does compile (I compiled with flags -O3 and -finline-functions).

I expected the program to have no output, as the condition for the while loop should evaluate to false. However, I got the following output from the program (printed in the while loop):

"it != mMap.end(): 0"

The output is particularly odd, given that the printed value (i.e., 0 or "false") is also the condition for the while loop.

After the print, the program segfaults because the iterator becomes invalid (via it++ in the while loop that should never have executed).

I guess this can all be chalked up to the missing return value. But, I find it surprising that the code behaves so pathologically simply because a return value isn't supplied. I'd appreciate any insight into understanding what's happening at a deeper level.

#include <iostream>
#include <tr1/unordered_map>

struct Test
{
  int Dummy (void) const
  {
    std::tr1::unordered_map<int, int>::const_iterator it = mMap.begin();
    while (it != mMap.end())
    {   
      std::cout << "it != mMap.end(): " << (it != mMap.end()) << std::endl;
      it++;
    }   
  }
  std::tr1::unordered_map<int, int> mMap;
};

int main (void)
{
  Test test;
  test.Dummy();
  return 0;
}

Upvotes: 1

Views: 186

Answers (2)

BullyWiiPlaza
BullyWiiPlaza

Reputation: 19195

You should turn on warnings using -Wextra and -Wall in gcc which will e.g. enable the warning Control reaches the end of a non-void function so you will hopefully not forget about fixing stuff like that. To enforce it, enable the compiler flag -Werror.

Not returning a value invokes undefined behavior so the compiler is allowed to either return a garbage value or crash your program (this is what clang typically does) if the function returns. This is bad and you should never keep broken code like that. For additional insight you can use a disassembler and see what your compiler did at the end of the function.

Upvotes: 0

Mestkon
Mestkon

Reputation: 4046

Returning from a non-void function without supplying a return value is underfined behavior, and therefore the compiler can do whatever it wants.

What the compiler has done in this case in particular, seems to be that it has spotted that skipping the loop would trigger UB and therefore assumes the loop is entered at least once. Therefore it assumes that it can safely enter the loop without checking the condition as the compiler trusts that the author of the program did not invoke any undefined behavior.

This is of course speculation from my part.

Upvotes: 3

Related Questions