I have a TestClass
with a const&
member variable. I know from various places and own experiences that it is a bad idea to initialize this const&
with the reference to a temporary value. So I was quite suprised that the following code will compile fine (tested with gcc-4.9.1
, clang-3.5
, and scan-build-3.5
) but fail to run properly.
class TestClass {
public:
// removing the "reference" would remove the temporary-problem
const std::string &d;
TestClass(const std::string &d)
: d(d) {
// "d" is a const-ref, cannot be changed at all... if it is assigned some
// temporary value it is mangled up...
}
};
int main() {
// NOTE: the variable "d" is a
// temporary, whose reference is not valid... what I don't get in the
// moment: why does no compiler warn me?
TestClass dut("d");
// and printing what we got:
std::cout << "beginning output:\n\n";
// this will silently abort the program (gcc-4.9.1) or be empty
// (clang-3.5) -- don't know whats going on here...
std::cout << "dut.d: '" << dut.d << "'\n";
std::cout << "\nthats it!\n";
return 0;
}
Why does none of the two compilers warn me at compile-time? See also this ideone, with some more testing going on.
Binding constants provide a fundamental measure of the affinity of a solute to a ligand; hence the determination of binding constants has been an important step in describing and understanding molecular interactions. Many techniques have been developed to measure binding constants.
Definition. In chemistry and biochemistry, the affinity constant is the reciprocal of the dissociation constant, where both are equilibrium constants describing the strength of binding between a catalyst such as an enzyme or ribozyme and its substrate.
The smaller the KD value, the greater the binding affinity of the ligand for its target. The larger the KD value, the more weakly the target molecule and ligand are attracted to and bind to one another.
The binding constant can be calculated by dividing the on-rate by the off-rate, this is also equal to the concentration of ligand-molecule complex divided by the concentration of ligand times the concentration of the receptor molecule.
No warning as no offense:
local const
references prolong the lifespan of the variable.
The standard specifies such behavior in §8.5.3/5, [dcl.init.ref], the section on initializers of reference declarations. The lifetime extension is not transitive through a function argument. §12.2/5 [class.temporary]:
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (§12.6.2 [class.base.init]) persists until the constructor exits. A temporary bound to a reference parameter in a function call (§5.2.2 [expr.call]) persists until the completion of the full expression containing the call.
You can have a look at gotw-88 for an extended and more readable discussion on this topic.
So is it your code correct? Nope, and its execution will lead to undefined behaviour. The real problem in your code snapshot is that the Undefined Behaviour is caused by the mix of two perfectly legal operations: the call of the constructor passing a temporary object (whose life spans inside the constructor block) and the binding of the reference in the constructor definition.
The compiler is not smart enough to detect this explosive statement combination, so this is why you don't get any warning.
Binding a const &
to a temporary is valid and the compiler will ensure that the temporary will live at least as long as the reference. This allows you to do things like pass string literals into functions expecting a const std::string &
.
In your case however you are copying that reference and thus the lifetime guarantee no longer holds. Your constructor exits and the temporary is destroyed and you are left with a reference to invalid memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With