Hi,
On Wed, 16 Jan 2013, Thomas Preud'homme wrote:
$ cat long_long.c
#include <stdio.h>
int main(void)
{
char *p = NULL;
p -= 0x700000000042;
/* from pointer to integer types */
printf("%d %d %ld %ld %lld %lld\n",
(int)p, (unsigned int)p,
(long)p, (unsigned long)p,
(long long)p, (unsigned long long)p);
return 0;
}
Pointer to integer conversions (and back) are implementation defined, the
only requirement being that if the integer type is (u)intptr_t that a
pointer converted to that one and back to a pointer shall compare equal to
the original pointer.
So, depending on how the compiler implements this conversion (and
documents this) one might get different results:
$ gcc -o long_long long_long.c && ./long_long
[SNIP gcc warnings]
-66 -66 -66 -66 -66 -66
This is a correct result for ILP32 (i.e. 32bit code). GCC sign extends
pointers when the pointer representation needs fewer bits than the target
type.
$ clang -o long_long long_long.c && ./long_long
-66 -66 -66 -66 4294967230 4294967230
And this is also a correct result for 32bit code, when the compiler
defines pointer to integer conversion to be zero-extending when the target
type has more bits than a pointer. IMO sign-extending is more useful, and
as GCC set the precedent a long time ago I would declare clang to at least
have an QoI issue with compatibility with GCC. In other words: tcc has no
bug here.
Ciao,
Michael.
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel