About Me
Sunday, August 20, 2006
What is the problem with this C++ code ?
class FooBar
{
public:
FooBar(int val): _val(val) {};
~FooBar() {};
void Foo(int val)
{
_val += Bar(val);
};
int Val() { return _val; };
private:
int Bar(int val)
{
_val = val;
return _val;
};
int _val;
};
int main()
{
FooBar fb(42);
fb.Foo(1);
int val = fb.Val();
return 0;
}
This one of the very subtle problem facing a C++ developer.
The problem lies in the code
_val += Bar(val);
In short the evaluation of this expression is dependent on a compiler implementation. So based on whether you compile it using gcc or someother compiler you might get either 43 or 2.
The question is why is it compiler dependent ?
The reason is that there are no sequence points within the expression += .
Hence the value of _val in the expression depends on whether the compiler uses the value of _val after the side effect of Bar(val) or does it use the value before the Bar(val).
As per the C++ specification the only guarantee is that all side-effects of a previous evaluation shall be complete before the sequence point for the expression is evaluated. But within a single sequence point, the side effects can take place at any time.
hence some compiler might implement this as
int temp = Bar(val);
_val = _val + temp;
hence here the value of _val is taken as 1 and hence it becomes 2 after the expression is evaluated.
While some other compiler might implement this as,
int temp = 0;
_val = _val + (temp = Bar(val));
hence as we see within the sequence point the side-effect is completed, but when it happens is not specified by the C++ standard. Now is this a problem in the standard is a debatable question. I am not sure how JAVA deals with such scenarios ?
Wednesday, June 21, 2006
Koenig lookup
Now what in the world does Koenig Lookup mean (ofcourse with respect to C++ !! ).
Koenig Lookup specifies how unqualified functions are resolved based on the namespaces to which the parameters belong.
Did that give any idea ? I knew that wouldn't. ;-)
Ok. So let me show it to you with a neat example.
Consider a namespace
namespace NS
{
class myclass
{ ... // some data members and member methods.
};
void operationOnMyClass(myclass& c);
}
int main(int argc, char* argv[])
{
NS::myclass obj;
operationOnMyClass(obj);
}
Under normal circumstances of resolving the non-member function operationonMyClass, the global namespace would be searched for a definition for operationOnMyClass. Since there is no implementation in global namespace it will fail.
Instead the compiler can be a little bit more intelligent where in it knows that the function parameter belongs to namespace NS. Hence it also searches the namespace NS apart from the global namespace. Hence it finds the correct implementation for operationOnMyClass.
This lookup using namespace information is known as Koenig lookup. This feature is also known as Argument Dependent Lookup(ADL) or Argument dependent name lookup.
This is exactly how the operator << gets resolved to STL namespace when using
std::cout << "Found the implementation !";
The std::cout being the first parameter to the operator << method , the compiler searches the namespace stl and finds the implementation.
Thats all for now. Will be back with more such intricate tricks of C++ later.