Thursday, February 21, 2008

A volatile reference and const reference

A volatile reference

void foo(volatile double& bar )
{
cout << bar << endl;
}

Above function accepts a reference to double. What happens if you call,

int nVal = 0;
Foo( nVal );

An error will be generated by the compiler specifying the conversion from ‘ int ’ to ‘ volatile double & ’ is not possible.

Why it shouldn’t cast?

A casting has to be don when an integer need to be passed to a method which takes double as input. When we do a standard conversion from int to double a temporary object will be created with the help of implicit conversion. A function which takes volatile reference parameter can change the value of the parameter. Now let us map these two things together. When we do the implicit conversion a temporary object is created and if we pass that temporary object to a method which accepts volatile reference what happens? The method may modify the temporary object which will not affect the original one. For example,

void foo(volatile double& bar )
{
bar = 0;
}

int nVal = 10;
foo(nVal);
cout << nVal;

What we expect at the output? Here we intended to set the value of nVal as 0. But what happens if the above code runs? An implicit conversion has to be done from into to double and the resultant temporary is passed to method foo. So function foo sets the value of temporary object instead of nVal. Now it is great to see why the function with reference to double doesn’t compile while called with int.


A constant reference

void foo(const double& bar )
{
cout << bar << endl;
}

Now what should happen? Function foo accepts a const reference to double which in terms guarantees no update to the parameter bar. In this case it is safe to pass a temporary object. So the compiler will allow the following call.

int nVal = 0;
Foo( nVal );

Conclusion

If a temporary object could be used for calling a volatile reference function there might have been many hard to find bugs.

No comments: