|
From: | Michael Matz |
Subject: | Re: [Tinycc-devel] Call for testing |
Date: | Thu, 17 Jan 2013 01:48:01 +0100 (CET) |
User-agent: | Alpine 2.00 (LNX 1167 2008-08-23) |
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.
[Prev in Thread] | Current Thread | [Next in Thread] |