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 <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

Hi,
--- Ursprüngliche Nachricht --- Von: Jerry Feldman <gaf@blu.org> 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

On Wednesday 29 March 2006 2:35 am, Verdi March wrote:
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 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 <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
participants (2)
-
Jerry Feldman
-
Verdi March