[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