[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>.