
How could moving boost_swap_impl::swap_impl to the boost namespace possibly cause a stack overflow?
David Abrahams wrote:
Sounds like an infinite recursion to me.
Yes, it is... The following little test program works fine when using the current trunk version of utility/swap.hpp. But it gets into infinite recursion when swap_impl is moved to the boost namespace: //////////////////////////////////////// #include <boost/swap.hpp> int main() { int i1 = 0; int i2 = 9; boost::swap(i1, i2); return i2; } //////////////////////////////////////// After moving swap_impl into the boost namespace, Visual Studio 2008 shows me the following call stack, before the overflow: boost::swap_impl<int>(int & left=0, int & right=9) boost::swap<int,int>(int & left=0, int & right=9) ... boost::swap_impl<int>(int & left=0, int & right=9) boost::swap<int,int>(int & left=0, int & right=9) boost::swap_impl<int>(int & left=0, int & right=9) boost::swap<int,int>(int & left=0, int & right=9) boost::swap_impl<int>(int & left=0, int & right=9) boost::swap<int,int>(int & left=0, int & right=9) main() __tmainCRTStartup() mainCRTStartup() So apparently, within boost::swap_impl, boost::swap<int,int> would be preferred over std::swap<int>, even while std::swap<T> is more specialized than boost::swap<T1,T2>. Isn't that weird? Note that the current version of swap_impl has a using-directive: template<class T> void swap_impl(T& left, T& right) { using namespace std; swap(left,right); } If swap_impl would have a using-declaration instead, "using std::swap", the infinite recursion would not occur. (But we've just replaced the using-declaration by a using-directive, to work around some ADL compiler bugs!) I still wonder if this infinite recursion is a compiler bug as well. But anyway, it's clear to me now that there's a good reason to keep swap_impl out of the boost namespace. :-) Kind regards, Niels