5
#include <iostream>
#include <string>
using namespace std;

string
crash()
{

}

int
noCrash()
{

}

int
main()
{
    crash(); // crashes
    // noCrash(); // doesn't crash
    return 0;
}

The function crash(), crashes with Mingw g++ 4.6.2 and the function noCrash() executes with no issues. Why does the function returning string crash without a return statement?

TheFuzz
  • 2,607
  • 6
  • 29
  • 48
  • 1
    I'm surprised it compiles at all. – Paul Mitchell Jun 19 '12 at 07:13
  • @PaulMitchell: The program is syntactically and semantically valid... even if it is sure to cause _undefined behavior_ if it is actually run. – CB Bailey Jun 19 '12 at 07:15
  • 1
    @Paul me too, I even asked question like: WTF, why is this a warning in g++, and not an error. – NoSenseEtAl Jun 19 '12 at 07:28
  • 1
    @NoSenseEtAl: See this related question: http://stackoverflow.com/questions/1735038/why-not-all-control-paths-return-a-value-is-warning-and-not-an-error – Asha Jun 19 '12 at 07:36

4 Answers4

8

Both are undefined behaviors, even noCrash can crash.

Asha
  • 11,002
  • 6
  • 44
  • 66
8

From standard 6.6.3/2

A return statement without an expression can be used only in functions that do not return a value, that is, a function with the return type void, a constructor (12.1), or a destructor (12.4). A return statement with an expression of non-void type can be used only in functions returning a value; the value of the expression is returned to the caller of the function. The expression is implicitly converted to the return type of the function in which it appears. A return statement can involve the construction and copy of a temporary object (12.2). Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
6

A lot of this is undefined, but it arguably helps to understand the practical reasons for such observations - it can help in troubleshooting and even performance and spatial design.

So, in a practical sense, if the function fails to return a value, it's basically failing to set the register or memory where that value will be expected by the caller; it appears to return whatever garbage used to be there. If the return type is int, you've just got yourself a garbage value, but for strings you have a garbage value that's meant to point (directly or indirectly) to the heap memory used by the string to store the textual value and possibly some reference counter or other management data. Later in the program, the calling code will try to deallocate that heap memory by deleting the pointer. Deleting a pointer with a garbage value's quite likely to crash your program.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
5

Probably because when you call crash the compiler attempts to destroy a temporary std::string object that was never created.

As both functions have undefined behavior speculation is somewhat futile.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656