2

Consider the code:

int& getValue()
{
  int i = 10;
  return i;
}

This leads to compiler warning:

warning: reference to local variable `i' returned

I understand the reason for the warning. I am returning the reference to a local variable which is destroyed as soon as I go out of scope.

My question is: Why is this even allowed? Why doesn't the compiler simply give an error instead of a warning?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
toutnom
  • 244
  • 1
  • 7
  • Because that would prevent tricks like code to detect whether the stack grows up or down! (Only half joking.) BTW, `-Werror` is your friend. – vanza Oct 15 '14 at 02:30
  • If you want this kind of checks, use Rust, not C++. – o11c Oct 15 '14 at 02:41

2 Answers2

5

It is undefined behavior the compiler is not even obligated to provide a diagnostic let alone make it an error. The draft C++ standard in section 1.4 Implementation compliance says:

The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior.”

This is mainly due to the fact that it is not always trivial for the compiler to determine when undefined behavior is present and forcing the compiler to detect all cases would be considered an undue burden.

Although modern compilers are pretty good at catching all sorts of bad behavior include undefined behavior, with gcc and clang I find the following set of flags to be helpful: -Wall -Wextra -Wconversion -pedantic.

You can turn these into errors you can use -Werror which I recommend strongly. It forces you to understand why each warning is being generated and have the discipline to find better solutions which will save you a lot of pain in the long run.

Note, the one case where we can probably force an error for detectable undefined behavior is when we are assigning the result of a constexpr function to a constexpr variable since constant expression exclude undefined behavior.

So the following C++14 code:

constexpr int& getValue()
{
  int i = 10;
  return i;
}

int main()
{
    constexpr int &p = getValue();
    //...
}

generates the following error using clang:

error: constexpr variable 'p' must be initialized by a constant expression
    constexpr int &p = getValue();
                   ^   ~~~~~~~~~~
Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
1

It's because what you're asking the compiler to compile can be compiler. Broadly speaking, errors are supposed to indicate that your code can't be comprehended; warnings merely indicate that you've possibly made a mistake (in this case: triggering undefined behaviour).

Tommy
  • 99,986
  • 12
  • 185
  • 204