Are pointers to be supposed to be sign or zero extended to wider integers?
Richard Guenther
richard.guenther@gmail.com
Fri Feb 12 11:19:00 GMT 2010
On Fri, Feb 12, 2010 at 10:41 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> It seems pointers are sign extended to wider integers, is that intentional?
> It certainly contradicts the comment in convert_to_integer:
> switch (TREE_CODE (intype))
> {
> case POINTER_TYPE:
> case REFERENCE_TYPE:
> if (integer_zerop (expr))
> return build_int_cst (type, 0);
>
> /* Convert to an unsigned integer of the correct width first, and from
> there widen/truncate to the required type. Some targets support the
> coexistence of multiple valid pointer sizes, so fetch the one we need
> from the type. */
> expr = fold_build1 (CONVERT_EXPR,
> lang_hooks.types.type_for_size
> (TYPE_PRECISION (intype), 0),
> expr);
> return fold_convert (type, expr);
> but the comment is newer than the sign extension.
>
> void
> foo (long long l)
> {
> if ((l >> (sizeof (void *) * __CHAR_BIT__ - 1)) == 1)
> __builtin_puts ("pointers zero extend to wider integers");
> else if ((l >> (sizeof (void *) * __CHAR_BIT__ - 1)) == -1)
> __builtin_puts ("pointers sign extend to wider integers");
> }
>
> int
> main (void)
> {
> int i;
> if (sizeof (&i) < sizeof (long long))
> foo ((long long) &i);
> return 0;
> }
Your program prints zero-extends for ICC.
Probably the behavior is undefined and we get a warning anyway:
t.c: In function ‘main’:
t.c:15: warning: cast from pointer to integer of different size
The middle-end requires an intermediate conversion to a same-precision
integer type to not fall into the trap deciding what sign a
pointer has.
Richard.
> Jakub
>
More information about the Gcc
mailing list