Thursday, October 25, 2007

(ADL & C++) == sucks

So I was recently writing some code in C++ and came across yet another of C++'s many quirks/pitfalls. This one is called ADL. Argument dependent lookup.

What that means is C++ will sometimes search non-explicitly available namespaces for symbols. I hope you are scratching your head right now. Yes, the whole point of namespaces is to prevent the possibility of namespace collisions. And yes, this "feature" prevents you from trusting namespaces.

From wikipedia here is an example of how this can screw you over:

    std::swap(a, b);

...may or may not be the same as the behavior of...

    using std::swap;
    swap(a, b);

...if in the vastness headers your project includes there is a function called swap, under the "right" conditions it may be used instead of the one you expect.

Yes, there are situations where it is useful. But it pisses me off none-the-less. If you are interested, read the wiki article here:

http://en.wikipedia.org/wiki/Argument_dependent_name_lookup

Sometimes I really hate C++. I hope D will be my savior.

3 comments:

Catskul said...

Not sure how long past bin will last, but heres my example of the problem showing its ugly head:

http://cpp.tastethepaste.org/1000

pizer said...

I know this comment is a very late response. I hope you appreciate ADL by now because without it many things (generic programming or operator<< for streams) would be a big pain in the a**.

ADL could be a little less eager, though.

Cheers!
- P

blag said...

I agree with pizer.

ADL is a consistent and somewhat elegant solution to the problem of excessive verbosity.

I've always wanted something similar for enum arguments to a function (writing just SOME_SPECIAL_CONSTANT instead of TheNamespace::TheClass::SOME_SPECIAL_CONSTANT) for arguments of the right type.

On the ugly side, C++'s swap function is abhorrent. The idea was that users would be able to supply their own swap functions, but it's against the rules of the standard to add anything to the std namespace. Instead, they would supply swap in their own namespace (possibly the global namespace).

But code using the swap function can't rely on a swap function being specialized for the types its using, and has to be able to fall back on the std version (which just uses a temp variable). What this means is that all code that uses a possibly-specialized swap (all template code) must 'using std' before calling swap unqualified, just-in-case there is no specialized version.

boost::swap restores some sanity to this mess, but by the time you find it, you've lost a lot of respect for C++.

(Sorry for commenting on an old blog post, but I was doing the 'wikipedian' thing on a Google search result.)

Post a Comment

No flamebait allowed.