[C++-sig] boost/python 1.33.1 breaks aliasing rules

David Abrahams dave at boost-consulting.com
Thu Dec 8 06:35:12 CET 2005

Philipp Thomas <pth at suse.de> writes:

> * Philipp Thomas (pth at suse.de) [20051207 14:27]:
>> I'll do a patch that changes all affected places
> And here is the patch I'm going to be using for SUSE Linux:
> --- libs/python/src/dict.cpp
> +++ libs/python/src/dict.cpp
> @@ -28,9 +28,9 @@
>  detail::new_reference dict_base::call(object const& arg_)
>  {
> +    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyDict_Type };
>      return (detail::new_reference)PyObject_CallFunction(
> -        (PyObject*)&PyDict_Type, "(O)", 
> -        arg_.ptr());
> +        pun.pop, "(O)", arg_.ptr());
>  }

That's unacceptable for Boost because, IIUC, it introduces undefined
behavior in Boost.Python (reusing the bit pattern for one type of
pointer as another type of pointer) where there is currently none
(since Python will always be compiled with options that make such
aliasing OK).  Even if it works for GCC, it could break some other
compiler, and the new code could cause warnings with another compiler
where there currently is none.  

In fact, I don't see how this union trick can do anything other than
suppress the warning.  It can't possibly fix a real problem.  If
Python is compiled without -fno-strict-aliasing, it will be free to
make invalid assumptions about these pointers aliasing one another,
and the use of the union will do nothing to stop that.

Fundametally, I need a solution that doesn't mess up other compilers.
There is code in boost/python/cast.hpp that does the same kind of
aliasing and yet apparently doesn't generate any warnings (or you'd
have included it in your patch).  So maybe the best solution would be
just to use boost/python/cast.hpp.  At least then all the "evil" is
encapsulated in one place and can be tweaked for specific compilers.

Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list