Skip to content

Reference over temporaries #10

@jhjourdan

Description

@jhjourdan

I have a problem with the way the track and dxxxx functions take their
arguments. Let's take the following example (it uses the same idioms as
CppBugds examples):

MCModelboost::minstd_rand m(model);
m.track(lambda).dgamma(0.1, 0.1);

The dgamma function takes its arguments by reference and do not store a
copy of its arguments. Moreover, 0.1 is stored in a temporary before being
passed to dgamma. Thus, the compiler is allowed to deallocate the memory
used for this temporary just after the call, and use it for something
else. However, this value will be used afterward during the sampling. So,
we have a problem, because the value used during the sampling can be
different.

For some reason, it seems like this problem actually happens only for gcc

= 4.7, with optimisations enabled. That is why the problem has never been
discovered before.

I have different ideas for solving this problem. None of them are
perfect. Please give me your thoughts about them:

1- Ask the user code not to pass temporaries to these functions. This makes
the user code heavier, but there is not change of the library code.

The client code would be:

double zeropointone = 0.1;
m.track(lambda).dgamma(zeropointone, zeropointone);

2- For each of these parameters, give two overloads of the functions. One
will take a pointer to the value, and the other will take the value (not a
reference to it !). The second one first stores the value in a safe place
before calling the first version.

The client code would be:

double zeropointone = 0.1;
m.track(&lambda).dgamma(0.1, 0.1);

Pros: flexibility for the user
Cons: no backward compatibility, somewhat less clean user code (and the
user has not to forget to put the &).

3- Idem as 2-, but with const references in place of pointers. That is, the
copy will take place only when the given expression is either an rvalue or
a const variable. The typical client code would not change:

m.track(lambda).dgamma(0.1, 0.1);

Pro: backward compatibility, basic user code more intuitive.
Cons: even if it seems to be a good criterion for most cases in practice,
there is no good reason for using constness for this purpose. In
particular, the non-copying versions of the dxxx functions will have
non-const parameter but const behaviour.

3bis- Idem as 3, but using rvalue references in place of const references

Pro: backward compatibility, basic user code more intuitive
Cons: using rvalue-references which are a new feature of C++11 that nobody
really understand in details...

Thanks !

Jacques-Henri Jourdan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions