3

I wrote a simple function to return a string for me to display on the screen.

static std::string  myFun(int myId){
  std::ostringstream stream;
  int myStatus;
  if(get_status(&myStatus)) stream << get_error();
  else{
    stream << "my status:" << myStatus;
  }
    return stream.str();
}

The code itself is probably not important. But I include it just in case.The problem I encountered is because in my original attempt, I forget to include the return statement

return stream.str();

The compiler compiled with no error, but when I run it. The program keep getting messages like

Aborted(core dumped)

I freak out and I search I stackoverflow and installed valgrind and everything. Then I check the code, I realize I simply forget to include the return statement! I would expect the compiler to notice these kinds of mistake.

Can someone explain to me why the compiler cannot detect the error?

SunnyIsaLearner
  • 750
  • 2
  • 13
  • 26
  • 2
    Try compiling with the -Wall option :-) – George Apr 21 '17 at 16:51
  • Did you try enabling warnings? Not returning anything, from the function, when you're supposed to, is, simply, undefined behavior. – Algirdas Preidžius Apr 21 '17 at 16:51
  • 1
    I usually go with `-Wall -Wextra -pedantic-errors` (at least) – Galik Apr 21 '17 at 16:52
  • so something like this is actually a "warning" ok! I will try this – SunnyIsaLearner Apr 21 '17 at 16:52
  • Well, it is a warning, but it's not a guarantee that the resulting code will work correctly; and most likely, not. – Sam Varshavchik Apr 21 '17 at 16:53
  • 1
    Simplified rule of thumb: Compiler error = bad syntax. Code cannot be parsed to create a program. Compiler warning = Syntax correct and can be parsed into a program, but the logic is probably wrong. – user4581301 Apr 21 '17 at 16:54
  • It is undefined behavior, see [this similar question](http://stackoverflow.com/a/20614325/1708801) as stated there you should get a warning if you use the right flags. – Shafik Yaghmour Apr 21 '17 at 16:55
  • On the "why" part: 'if(rand()%2) return retval;' - call this in a loop. Any opaque function is basically rand() to the compiler, i.e., it cannot reasonably deduce if it will return. That'd be equivalent to the halting problem. Now, for some simple cases it can and will, if you turn on the warnings others suggested. – lorro Apr 21 '17 at 17:26

2 Answers2

7

The behaviour of code that doesn't have a return value on all control paths of a non-void function is undefined. (C++ has plenty of undefined constructs; perhaps a consequence of favouring maximum performance and portability over kindness to developers.)

A good compiler will warn you of this and will even provide you settings to upgrade that warning (along with others) to an error. Consult your compiler documentation.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • A diagnostic is not required because it cannot be proven in the general case. A warning in simple cases is the best we can get. – Lightness Races in Orbit Apr 21 '17 at 17:35
  • Absolutely! Java have attempted to define reachability but every computer scientist freshman knows it's not possible in full generality. – Bathsheba Apr 21 '17 at 17:36
  • @BoundaryImposition No one said a warning is required, just that good compilers typically provide them. It doesn't have to prove anything to generate a warning about suspicious code. – Barmar Apr 21 '17 at 19:47
  • @Barmar: No one claimed that anybody said that a warning is required. Did you accidentally miss my answer, posted 3 hours before your comment, which basically said the exact same thing? Thanks for your input though I guess. – Lightness Races in Orbit Apr 21 '17 at 23:42
  • You commented **A diagnostic is not required because it cannot be proven in the general case.** What was that comment referring to? – Barmar Apr 22 '17 at 00:18
  • @Barmar: What do you mean? Referring to? To the question, to the topic.... if you're asking whether I was trying to contradict something Bathsheba said, the answer is no: I was only adding to what Bathsheba said. – Lightness Races in Orbit Apr 25 '17 at 01:34
  • @BoundaryImposition That was my misunderstanding then. I thought you were suggesting there was something wrong when they wrote "A good compiler will warn you of this" – Barmar Apr 25 '17 at 01:37
2

Because, in the general case, it's not possible for the compiler to prove that your function doesn't return. What if it always throws an exception, instead, but that exception comes from a function defined in another translation unit e.g. a linked library?

Thus the language standard cannot require compilers to error out; thus, they don't bother.

However, in simple examples like this, the compiler can tell and, when it can, it will warn you. If you turn warnings on. Which you should do now.

Ultimately, though, in C++, spotting this kind of thing is the programmer's responsibility. Static analysis tools can help you to avoid such mistakes if you find your eyesight insufficient. :)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Nice answer but I don't think the compiler can really tell even in this case - get_status might be defined in another translation unit and always throw an exception. – Bathsheba Apr 21 '17 at 17:39
  • @Bathsheba I think compilers just assume that functions normally return, and base their warnings about data and control flow on this. Since it's just a warning, it doesn't have to be perfect. – Barmar Apr 21 '17 at 19:45