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

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


Philipp Thomas <pth at suse.de> writes:

> * Ralf W. Grosse-Kunstleve (rwgk at yahoo.com) [20051205 17:54]:
>
>> It looks to me like you are effectively asking for a re-write of C Python.
>
> I've now looked at the Python sources and the Python folks decided to use
> -fno-strict-aliasing instead of fixing the code 
> ( http://sourceforge.net/tracker/index.php?func=detail&aid=766696&group_id=5470&atid=105470 ).

Which, AFAICT, means that our casts aren't hurting anybody, regardless
of whether we use -fno-strict-aliasing.  Right?

>> I don't think we can do anything about this in boost. 
>
> Two things would be possible, both specific to gcc:
>
> 1) use -fno-strict-aliasing (valid for gcc >= 3.0), preferably only for the
>    boost python libs
>
> 2) use a union for type punning, i.e. :
>
> *** str.cpp     2005/12/07 12:55:17     1.1
> --- str.cpp     2005/12/07 13:02:18
> ***************
> *** 8,16 ****
>
>   detail::new_reference str_base::call(object const& arg_)
>   {
>       return (detail::new_reference)PyObject_CallFunction(
> !         (PyObject*)&PyString_Type, "(O)",
> !         arg_.ptr());
>   }
>
>   str_base::str_base()
> --- 8,17 ----
>
>   detail::new_reference str_base::call(object const& arg_)
>   {
> +     union { PyTypeObject *ptp; PyObject *pop; } pun = { &PyString_Type };
> +
>       return (detail::new_reference)PyObject_CallFunction(
> !         pun.pop, "(O)", arg_.ptr());
>   }
>
> using a union to pun a type is a gcc specific solution. 

It's nonportable in other ways than you're indicating, as far as I can
tell.  I don't think there's any guarantee that the bit pattern for
PyObject* is the same as the one for a PyTypeObject* at the same
address.  The (PyObject*) cast is essentially a reinterpret cast from
PyTypeObject* to PyObject*, where the union performs, essentially, a
reinterpret cast of a PyObject*& to a PyTypeObject*&, which could be a
completely different thing.

> I'll do a patch that changes all affected places that I can send
> here if there is interest to add it to boost. Otherwise I'll only
> use the patch for the version of boost in SUSE Linux.

To avoid affecting other compilers I suppose your patch would require
the addition of numerous #ifdef blocks, or it would have to turn all
the CPythonish casts into macro invocations that expand into some
compiler-specific construct... right?

I would strongly oppose the former, but the latter might be no worse
(and may be a little better) than leaving the C-style casts in there.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list