0

Consider the following program:

int b(int in)
{
    return in + 1;
}

int a(int in)
{
    b(in); // return statement forgotten
}

int main()
{
    std::cout << "returned: " << a(5) << "\n"; 
}

VC++ gives an error about the missing 'return'. Intel Compiler only issues a warning (missing return statement at end of non-void function "a") but most surprisingly at runtime the code does return the correct value and the printout is:

returned: 6

How come?

Using Intel C++ compiler 19.0

gil_mo
  • 575
  • 1
  • 6
  • 27
  • 5
    Undefined behavior can even do things like appear to work. – Eljay Jan 24 '20 at 15:24
  • https://en.cppreference.com/w/cpp/language/ub – Jesper Juhl Jan 24 '20 at 15:26
  • 3
    @Slava Programs that have UB are worth considering, for the purpose of determining whether or not they are UB. Many questions posted here are about why code doesn't behave as expected. Its not always obvious to everyone that code is UB or even what UB is. – François Andrieux Jan 24 '20 at 15:29
  • 1
    @FrançoisAndrieux I did not say UB, I said obvious UB and this case listed in the duplicate "Not returning a value from a value-returning function (directly or by flowing off from a try-block)" – Slava Jan 24 '20 at 15:30
  • +1 Francois, what one considers as UB might just as well be some compiler weird novelty introduced in a C++23 or such... – gil_mo Jan 24 '20 at 15:30
  • My C++ teacher had a proverb. "When behaviour is undefined everything can happen. Don't be surprised." – honzakuzel1989 Jan 24 '20 at 15:31
  • 1
    @FrançoisAndrieux let's start to condiser `i=i++;` questions again, just in case UB is not obvious to some one. – Slava Jan 24 '20 at 15:33
  • @honzakuzel1989 I would be surprised if it satarted to rain money... :) – anastaciu Jan 24 '20 at 15:33
  • 2
    @anastaciu It is definitely possible when behaviour is undefined - the sky can fall and so on :). – honzakuzel1989 Jan 24 '20 at 15:38
  • Try to run the code with optimizations enabled. – Daniel Langr Jan 24 '20 at 16:25
  • 1
    _How come?_ You can always check the [generated assembly](https://godbolt.org/z/fpjg92). The explanation is that the return value of a `a` call is passed in `EAX` register with x86 calling conventions. If the result of the calculation inside `b` is stored also in `EAX`, and this register is not changed until `a` returns, then, in `main`, the correct returned value is taken from `EAX`. It's basically just a matter of coincidence that the _working_ assembly has been generated. You just cannot count on it. The next time you run a compiler it can decide otherwise. – Daniel Langr Jan 24 '20 at 16:29
  • @gil_mo _what one considers as UB_ — It's definitely not about what _one considers_. It's about what the Standard says. Of course, the version of the Standard you are compiling your code against. – Daniel Langr Jan 24 '20 at 16:32

0 Answers0