[Python-Dev] ANSI strict aliasing and Python
Tim Peters
tim.one@comcast.net
Thu, 17 Jul 2003 22:44:41 -0400
[python-dev-admin@python.org]
> [Neil Schemenauer]
>> Recently the GCC option -fno-strict-aliasing flag got added. The
>> intention was to silence GCC warnings like this:
>>
>> ../Objects/object.c: In function `PyObject_IsTrue':
>> ../Objects/object.c:1565: warning: dereferencing type-punned
>> pointer will break strict-aliasing rules
>
> This is strange (according to me). The real point of adding that
> option would be to prevent bad code generation in the presence of
> pretty common non-standard C code, but I don't know why a compiler
> would complain about PyObject_IsTrue:
>
> int
> PyObject_IsTrue(PyObject *v)
> {
> int res;
> if (v == Py_True) THIS IS LINE 1565 FOR ME
> return 1;
> if (v == Py_False)
> return 0;
> if (v == Py_None)
> return 0;
> else if (v->ob_type->tp_as_number != NULL &&
> v->ob_type->tp_as_number->nb_nonzero != NULL)
> res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
> else if (v->ob_type->tp_as_mapping != NULL &&
> v->ob_type->tp_as_mapping->mp_length != NULL)
> res = (*v->ob_type->tp_as_mapping->mp_length)(v);
> else if (v->ob_type->tp_as_sequence != NULL &&
> v->ob_type->tp_as_sequence->sq_length != NULL)
> res = (*v->ob_type->tp_as_sequence->sq_length)(v);
> else
> return 1;
> return (res > 0) ? 1 : res;
> }
>
> There are two reasons I'm confused:
>
> 1) The indicated line merely compares two addresses -- there's
> no dereferencing there.
>
> 2) There's nothing in the function that alters memory -- it
> simply doesn't matter whether non-standard aliasing exists in
> this code.
>
> When a warning makes no sense (as it appears to me in this case),
> trying to rewrite code to shut it up is a poke-and-hope waste of
> time. If it were pointing out an actual aliasing problem, fine.
>
>> It looks like most (maybe all) of those warnings are triggered by
>> Py_True and Py_False. Is there some other way of defining Py_True
>> and Py_False so that we can avoid those errors? Maybe it's a lost
>> cause anyhow, I don't really understand the ANSI spec on this issue.
>
>> ...
Here's a short program, illustrating why test_strptime fails if it's run
after test_logging, with no other tests between them:
"""
import locale
if 0:
locale.setlocale(locale.LC_ALL, '')
import _strptime
print _strptime.LocaleTime().lang
print locale.getdefaultlocale()[0]
print locale.getlocale(locale.LC_TIME)
"""
As-is on my box, it prints
en_US
en_US
(None, None)
Change "if 0" to "if 1", and it prints
English_United States
en_US
['English_United States', '1252']
Your turn <wink>.