tags:

views:

108

answers:

2

This was a bug I found in a server application using Valgrind.

struct Foo
{
    Foo(const std::string& a)
        : a_(a_)
    {
    }
    const std::string& a_;
};

with gcc -Wall you don't get a warning. Why is this legal code?

A: 

Self-assignment is allowed in C / C++ (and I'd consider this a flaw in the language).

From the memory model's point of view, Foo::a_ is simply some memory location and in the initializer list it gets assigned the value of another memory location, which in this special case unfortunately is the same location.

There is a similar flaw in C, where you can do this:

  void foo() 
  {
    int i = i;
  }
BjoernD
Actually the standard explicitly says that references don't have to occupy a memory location: `8.3.2/3 It is unspecified whether or not a reference requires storage (basic.stc)`
janks
+2  A: 

What you've got violates 8.3.2/4 A ... reference shall be initialized to refer to a valid object or function. So it is most certainly illegal.

Note that not all erroneous programs are required to be detected by the compiler, although I honestly would have thought this was one of them.

For what it's worth, g++ version 4.4.1 with maximal compiler warnings turned on happily accepts this program without a warning either:

int main(void)
{   
    int *p = 0;
    *p = 5;
}
janks
Compilers can't generally detect all violations, though. e.g. In `void f(int* p) { int /* ... */ }` the reference initialization may be legal in some calls to `f`, but not in others where `p` is passed as null.
Charles Bailey
It is understandable that the compiler can't detect something that is only valid or invalid at runtime, but in this case it can be statically proven that the reference can never be initialized by a real object.
janks
Yes, my point was only that because you can't _always_ detect bad reference initializations compiler implementers may not implement _any_ bad reference initialization checks even when there are cases where it is obviously bad to human eyes. It's potentially a lot of extra work (plus slower compiles) for potentially little gain.
Charles Bailey
What bothers me is that the compiler enforces you to initialize it but this can be satisfied with initializing it with itself.
Eddy Pronk
My copy of the standard is nearly a thousand pages long, so I'm not going to go look for an example, but there must be at least one error involving references that the compiler is required to diagnose in order to be conforming. I don't think they can get away with not implementing any checks whatsoever
janks