Sign in to follow this  

C++ hidden reference traps

This topic is 3849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What I mean by a 'reference trap':
struct Thing
{
    Thing (Foo& p_f) : f (p_f) {}
    Foo& f;
};

// Bar has an implicit conversion to a Foo
Bar b;
Thing t (b);
void Function (t);

Because of the implicit conversion, a temporary object, of type Foo is created when 'b' is passed to the constructor of 't'. But when the constructor for 't' is finished, the temp Foo object is destroyed. By the time 'Function' is called with 't', the Foo object 't.f' is referencing is long gone. Is there any chance of compilers ever being able to catch these types of bugs? I've found it to be pretty nasty because Debug builds appear to frequently survive unscathed, while Release builds crash (Turning on debug information in Release helps out fine, granted).

Share this post


Link to post
Share on other sites
Actually, a temporary variable may only be passed by const reference, so your example shouldn't compile.

As for compilers being able to catch this sort of thing, not really. They would need to know whether the function called makes a copy or uses a reference, which is impossible if the definition of the function is unavailable. A warning is definitely possible in the other cases, though.

Share this post


Link to post
Share on other sites
Yeah, I do try to avoid implicit conversions most of the time. They're constantly whispering 'convenience!' into my ears however, and sometimes I relent. BTW, do I get bonus points for const_cast? :)

Actual code:

template <typename Type, typename Initialiser1>
class InitialisingFactory1 // : Factory<Type>
{
public:

InitialisingFactory1 (Initialiser1& p_init1) : init1 (p_init1) {}
InitialisingFactory1 (const Initialiser1& p_init1) :
init1 (const_cast<Initialiser1&> (p_init1)) {}

virtual Type* operator() (void* address)
{
return new (address) Type (init1);
}

Initialiser1& init1;
};
// InitialisingFactory2/3/4 for more params



Because 'InitialisingFactory1' is just a temporary transportation (i.e. always on the stack) for constructor parameters, I thought I'd get away with a bit of hackery. Or foolishness, take you pick. :)

I guess the fundamental question is: Is there a better way?

Share this post


Link to post
Share on other sites

This topic is 3849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this