How to detect const reference to temporary issues at compile or runtime?

I've found recently that most of the errors in my C++ programs are of a form like the following example:

#include <iostream>

class Z
{
 public:
 Z(int n) : n(n) {}
 int n;
};

class Y
{
 public:
 Y(const Z& z) : z(z) {}
 const Z& z;
};

class X
{
 public:
 X(const Y& y) : y(y) {}
 Y y;
};

class Big
{
 public:
 Big()
 {
   for (int i = 0; i < 1000; ++i) { a[i] = i + 1000; }
 }
 int a[1000];
};

X get_x() { return X(Y(Z(123))); }

int main()
{
 X x = get_x();
 Big b;
 std::cout << x.y.z.n << std::endl;
}

OUTPUT: 1000

I would expect this program to output 123 (the value of x.y.z.n set in get_x()) but the creation of "Big b" overwrites the temporary Z. As a result, the reference to the temporary Z in the object Y is now overwritten with Big b, and hence the output is not what I would expect.

When I compiled this program with gcc 4.5 with the option "-Wall", it gave no warning.

The fix is obviously to remove the reference from the member Z in the class Y. However, often class Y is part of a library which I have not developed (boost::fusion most recently), and in addition the situation is much more complicated than this example I've given.

This there some sort of option to gcc, or any additional software that would allow me to detect such issues preferably at compile time, but even runtime would be better than nothing?

Thanks,

Clinton

Answers


I submitted such cases on the clang-dev mailing list a few months ago, but no one had the time to work on it back then (and neither did I, unfortunately).

Argyrios Kyrtzidis is currently working on it though, and here is his last update on the matter (30 Nov 23h04 GMT):

I reverted the previous commit, much better fix in http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20101129/036875.html. e.g. for

struct S {   int x; };

int &get_ref() {   S s;   S &s2 = s;   int &x2 = s2.x;   return x2; }

we get

t3.cpp:9:10: warning: reference to stack memory associated with local variable 's' returned
  return x2;
         ^~
t3.cpp:8:8: note: binding reference variable 'x2' here
  int &x2 = s2.x;
       ^    ~~
t3.cpp:7:6: note: binding reference variable 's2' here
  S &s2 = s;
     ^    ~
1 warning generated.

The previous attempt failed the self-hosting test, so I hope this attempt will pass. I'm pretty glad Argyrios is looking into it anyway :)

It isn't perfect yet, admittedly, as it's quite a complicated problem to tackle (reminds me of pointer aliasing in a way), but this is nonetheless a great step in the right direction.

Could you test your code against this version of Clang ? I'm pretty sure Argyrios would appreciate the feedback (whether it is detected or not).


Need Your Help

Creating a fully functional website while only using vanilla coding

javascript html css client-side-scripting server-side-scripting

When I say "Vanilla Coding", I am referring to websites that don't utilize server side coding (such as PHP, ASP, etc.), only HTML, JavaScript, and CSS.

how to embed XHTML in XML without DOCTYPE, CDATA or escapes?

xml xhtml schema doctype dtd

Is there any way embed XHTML entity references into XML text without the DOCTYPE DTD declaration? The DOCTYPE line is causing problems on the java server it's targeting.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.