0

Bird's eye view : Following code should generate error when compiled.

#include <iostream>
using namespace std;

class Soap{
    int r;
public:
Soap(){
    r = 0;
}
Soap operator+(Soap &s){
    Soap new1;
    new1.r = r + s.r; 
    return new1;}

Soap& operator=(const Soap &s){
    r= s.r;
}
};
int main(){
    Soap p,q,r;
    r = p +q; 
}

Acc. to the code my Operator= should return something of type Soap. But as I did not include any return statement in the code, the operator= should have returned void. But then it would have generated an error saying non-void fn. is returning void (while compiling). But no such error is genrated.

This means that the gcc is returning Something of type Soap here. But what is it returning??? And how's it doing it without even me telling it ?

Edit : As my q is being compared to the q - Why does flowing off the end of a non-void function without returning a value not produce a compiler error? I will make my Q more clear.

While running the code when operator= is called by the compiler (i.e. when the statement r = p+r is executed) the function returns a soap type. I never typed return statement in the fn operator=, leaving aside the fact that during actual running a soap type is being returned !!! So what is gcc doing here ? Is it initialising and returning a Soap object even without me typing it ?

Community
  • 1
  • 1
infiNity9819
  • 536
  • 2
  • 7
  • 19
  • 3
    [Compile with warnings.](http://coliru.stacked-crooked.com/a/6652d4fa836222c6) – chris Jan 27 '17 at 15:13
  • 1
    Possible duplicate of [Why does flowing off the end of a non-void function without returning a value not produce a compiler error?](http://stackoverflow.com/questions/1610030/why-does-flowing-off-the-end-of-a-non-void-function-without-returning-a-value-no) – François Andrieux Jan 27 '17 at 15:13
  • 1
    the compiler cannot check if a function declared to return something really does return something under all circumstances, so it could simply not check it. Not returning something from a non void function is UB – 463035818_is_not_an_ai Jan 27 '17 at 15:13
  • @chris Compiling with warning does give me the desired "warning". But When I checked the return type of the function it is indeed returning Soap type. I wanna know why and what is being returned by that operator= function when I'm not doing it. To Francois NO the other Q does not clear my doubt. I am asking a different Q. – infiNity9819 Jan 27 '17 at 15:16
  • @AV198, The answer to your question is in the link: *Flowing off the end of a function [...] results in undefined behavior in a value-returning function.* - It's returning nothing significant. It doesn't even have to return at all. Anything is a valid option. One possibility is returning the bits that happened to be there in the register and treating them as the return type. Assuming the compiler even decides to not optimize away code around these calls completely. – chris Jan 28 '17 at 03:28

3 Answers3

2

Your code has undefined behaviour. As the C++ standard says at §6.6.3/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.

With a sufficiently high warning level (-Wextra), GCC will print a diagnostic message for the broken code. That should be enough. Note that the C++ standard does not formally distinguish between warnings and errors, anyway.

As the behaviour is undefined, there simply is no answer to the question "But what is it returning???", because (very) strictly speaking, your code is no longer C++. The compiler creates a program from the code, but what the program does cannot be deduced from the C++ language rules.

In practice, from an implementation point of view, the program may crash because the caller may try to create an object from memory it should not be allowed to access. If you really really want to know what the compiler creates, then you can always look into the assembly.

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

When you invoke Undefined Behaviour, the compiler is permitted to do whatever it pleases. This includes crashing, doing exactly what you expect, deleting your code and do nothing, generate a program to format your harddrive or whatever. You simply cannot reason about a program containing UB.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
0

The compiler doesn't enforce that there is no way to reach the end of a function without stepping on a return statement. Of course, it is obvious that in a function with no return statement at all, the end of the function is likely to be reached.

Writing such a function is not prohibited (there could be exceptions, the function may be designed to never return...) but enabling warnings will let the compiler tell you something suspicious is going on.

file.cxx: In member function ‘Soap& Soap::operator=(const Soap&)’:
file.cxx:17:3: warning: no return statement in function returning non-void [-Wreturn-type]
Rémi Bonnet
  • 793
  • 5
  • 16
  • Ya enabling warning does give me the statement I wanted it to produce. But check the return type of operator= function. It is of Soap type. I never returned any soap type in that function. To make my statement more clear - Fn. actually returns SOap type while execution, which I never did. SO what soap object is being returned here ?? – infiNity9819 Jan 27 '17 at 15:22