Sign-unsigned widening conversion in C
Hi, is there a standard rule on widening conversion between signed and unsigned type? I found a reference from this URL: http://developers.sun.com/prodtech/cc/articles/ILP32toLP64Issues.html which also seems to be implemented by gcc. Can anybody confirm on this? TIA. int main() { unsigned int ui = 0xcabcdef2; long long ll_ui = ui; unsigned long long ull_ui = ui; int i = 0xcabcdef2; long long ll_i = i; unsigned long long ull_i = i; printf("ui=%x ll_ui=%llx ull_ui=%llx\n", ui, ll_ui, ull_ui); printf("i=%x ll_i=%llx ull_i=%llx%\n", i, ll_i, ull_i); return 0; } Execution result: ui=cabcdef2 ll_ui=cabcdef2 ull_ui=cabcdef2 i=cabcdef2 ll_i=ffffffffcabcdef2 ull_i=ffffffffcabcdef2 -- Regards, Verdi -- Echte DSL-Flatrate dauerhaft f�r 0,- Euro*! "Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl
On Tuesday 28 March 2006 11:44 am, Verdi March wrote:
Hi,
is there a standard rule on widening conversion between signed and unsigned type? I found a reference from this URL: http://developers.sun.com/prodtech/cc/articles/ILP32toLP64Issues.html which also seems to be implemented by gcc. Can anybody confirm on this? TIA.
int main() { unsigned int ui = 0xcabcdef2; long long ll_ui = ui; unsigned 32-bit int is assigned to a unsigned 64-bit long long, sign extension does not occur.
unsigned long long ull_ui = ui; unsigned 32-bit int is assigned to a signed 64-bit long long, sign extension does not occur because ui is unsigned. int i = 0xcabcdef2; long long ll_i = i; unsigned long long ull_i = i; i is a signed 32-bit int with the high order bit set. When assigned to i_ll, sign extension occurs. The sign extension occurs BECAUSE i is signed., whether of not the result is signed or unsigned. printf("ui=%x ll_ui=%llx ull_ui=%llx\n", ui, ll_ui, ull_ui); printf("i=%x ll_i=%llx ull_i=%llx%\n", i, ll_i, ull_i);
Execution result: ui=cabcdef2 ll_ui=cabcdef2 ull_ui=cabcdef2 i=cabcdef2 ll_i=ffffffffcabcdef2 ull_i=ffffffffcabcdef2
Absolutely.
First, the rules are in the C standards, (c89 and c99). I wrote a white
paper on this a couple of years ago:
http://h21007.www2.hp.com/dspp/files/unprotected/32bitto64bit_whitepaper.pdf
Basically, the C language rules can be confusing.
Take:
int i;
unsigned int ui;
long long ll_i;
ll_i = i + ui;
In this case 32-bit i is added to 32-bit ui resulting in a 32-bit UNSIGNED
expression. The resulting unsigned expression is then widened (without sign
extension) and assigned to ll_i;.
I explain some of the rules in my white paper.
--
Jerry Feldman
Hi,
--- Ursprüngliche Nachricht --- Von: Jerry Feldman
An: suse-programming-e@suse.com Betreff: Re: [suse-programming-e] Sign-unsigned widening conversion in C Datum: Tue, 28 Mar 2006 13:43:49 -0500
int main() { unsigned int ui = 0xcabcdef2; long long ll_ui = ui; unsigned 32-bit int is assigned to a unsigned 64-bit long long, sign extension does not occur.
unsigned long long ull_ui = ui; unsigned 32-bit int is assigned to a signed 64-bit long long, sign extension does not occur because ui is unsigned.
I guess it should the other way round :), I mean, the first one should be from unsigned 32-bit to signed 64-bit.
Absolutely. First, the rules are in the C standards, (c89 and c99). I wrote a white paper on this a couple of years ago:
http://h21007.www2.hp.com/dspp/files/unprotected/32bitto64bit_whitepaper.pdf Thanks for whitepaper, exactly what I was looking for. Initially I thought that the conversion rules are implementation dependendent. -- Regards, Verdi -- Bis zu 70% Ihrer Onlinekosten sparen: GMX SmartSurfer! Kostenlos downloaden: http://www.gmx.net/de/go/smartsurfer
http://h21007.www2.hp.com/dspp/files/unprotected/32bitto64bit_whitepaper. pdf
Thanks for whitepaper, exactly what I was looking for. Initially I thought that the conversion rules are implementation dependendent. The rules in the standard are very much implementation independent, but
On Wednesday 29 March 2006 2:35 am, Verdi March wrote:
there are some cases that are not covered by the standard, but your
examples were very clear.
The issues on sign extension can be counter-intuitive.
long long ll_i;
int i;
unsigned int j;
ll_i = i + j;
In this case, no sign extension because the expression, (i + j) is an
unsigned 32-bit expression. The unsigned 32-bit expresssion is widened
after the arithmetic.
ii_i = (long long)i + j;
In this case, i is widened with sign extension before the addition.
j is widened with no sign extension before the addition.
Additionally, the white paper is over a year old, and I may want to update
it at the end of my current project, please feel free to email me any
suggestions for improvement.
--
Jerry Feldman
participants (2)
-
Jerry Feldman
-
Verdi March