|  | Shifting in C |  | |
| | | manu |  |
| Posted: Wed Jul 23, 2008 7:08 am Post subject: Shifting in C |  |
Hi All,
I have executed the below program and got 0x1f as output...
Can anyone explain me why this output is coming instead of zero?
Compiler - gcc
int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
printf("%x\n",y);
return 1; } |
| |
| | | Richard Heathfield |  |
| Posted: Wed Jul 23, 2008 7:08 am Post subject: Re: Shifting in C |  |
manu said:
| Quote: | Hi All,
I have executed the below program and got 0x1f as output...
Can anyone explain me why this output is coming instead of zero?
Compiler - gcc
int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
|
If y has 65 or fewer bits (which it probably does), shifting 65 places invokes undefined behaviour. Therefore any result, or none, is admissible as far as implementation conformance is concerned.
3.3.7 Bitwise shift operators: "If the value of the right operand is negative or is greater than or equal to the width in bits of the promoted left operand, the behavior is undefined."
-- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
| |
| | | Martin Ambuhl |  |
| Posted: Wed Jul 23, 2008 7:08 am Post subject: Re: Shifting in C |  |
| |  | |
manu wrote:
| Quote: | I have executed the below program and got 0x1f as output...
Can anyone explain me why this output is coming instead of zero?
|
Because the result of the shift operator is undefined when the value of the right operand is greater than or equal to the width in bits of the left operand. You attempt to shift an unsigned long by 65, but this has a defined meaning only if sizeof(unsigned long)*CHAR_BIT is at least 66, which appears not to be true for your implementation.
Additionally:
Here you need #include <stdio.h>. Omitting a prototype for a variadic function (printf) is an error.
| Quote: | int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
printf("%x\n",y); ^^ |
"%x" is a specifier for an unsigned int, not for an unsigned long. "%x" is an error; it should be "%lx".
The only value with defined meaning for this return when you don't include <stdlib.h> is 0. If you #include <stdlib.h> you gain EXIT_FAILURE and EXIT_SUCCESS, making 3 values with defined meaning, and none of them is 1. > } |
| |
| | | Nick Keighley |  |
| Posted: Wed Jul 23, 2008 7:39 am Post subject: Re: Shifting in C |  |
On 23 Jul, 08:08, manu <manumg...@gmail.com> wrote:
| Quote: | I have executed the below program and got 0x1f as output...
Can anyone explain me why this output is coming instead of zero?
Compiler - gcc
int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
|
note C has a short version of this
y >>= x;
(someone else answered your actual question)
| Quote: | printf("%x\n",y); return 1; }
|
-- Nick Keighley |
| |
| | | manu |  |
| Posted: Wed Jul 23, 2008 8:52 am Post subject: Re: Shifting in C |  |
| |  | |
On Jul 23, 1:13 pm, Martin Ambuhl <mamb...@earthlink.net> wrote:
| Quote: | manu wrote: I have executed the below program and got 0x1f as output... Can anyone explain me why this output is coming instead of zero?
Because the result of the shift operator is undefined when the value of the right operand is greater than or equal to the width in bits of the left operand. You attempt to shift an unsigned long by 65, but this has a defined meaning only if sizeof(unsigned long)*CHAR_BIT is at least 66, which appears not to be true for your implementation.
Additionally:
Here you need #include <stdio.h>. Omitting a prototype for a variadic function (printf) is an error.
int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
printf("%x\n",y);
^^ "%x" is a specifier for an unsigned int, not for an unsigned long. "%x" is an error; it should be "%lx".
return 1;
^^^ The only value with defined meaning for this return when you don't include <stdlib.h> is 0. If you #include <stdlib.h> you gain EXIT_FAILURE and EXIT_SUCCESS, making 3 values with defined meaning, and none of them is 1.
}
|
Thanks Richard,Nick and Martin for valuable information.. |
| |
| | | Walter Roberson |  |
| Posted: Wed Jul 23, 2008 3:02 pm Post subject: Re: Shifting in C |  |
In article <H9OdnRwdEZvRRhvVnZ2dnUVZ8vidnZ2d@bt.com>, Richard Heathfield <rjh@see.sig.invalid> wrote:
| Quote: | manu said:
unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
If y has 65 or fewer bits (which it probably does), shifting 65 places invokes undefined behaviour. Therefore any result, or none, is admissible as far as implementation conformance is concerned.
|
Additional information: at least one common processor family takes the shift code modulo 32 when shifting 32 bit numbers. That's an implementation detail and perfect permitted by the standard section that Richard cited; just thought you might want to know how you ended up with the particular answer you did. -- "Ignorance has been our king... he sits unchallenged on the throne of Man. His dynasty is age-old. His right to rule is now considered legitimate. Past sages have affirmed it. They did nothing to unseat him." -- Walter M Miller, Jr |
| |
| | | Walter Banks |  |
| Posted: Wed Jul 23, 2008 7:32 pm Post subject: Re: Shifting in C |  |
Bet GCC masked x (and or mod) so shift would be <= of bits in y. If y had less than 65 bits then the shift would be 1 ie a result of 0x1f.
w..
manu wrote:
| Quote: | Hi All,
I have executed the below program and got 0x1f as output...
Can anyone explain me why this output is coming instead of zero?
Compiler - gcc
int main() { unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
printf("%x\n",y);
return 1; } |
|
| |
| | | Jack Klein |  |
| Posted: Wed Jul 23, 2008 11:55 pm Post subject: Re: Shifting in C |  |
| |  | |
On Wed, 23 Jul 2008 15:02:08 +0000 (UTC), roberson@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote in comp.lang.c:
| Quote: | In article <H9OdnRwdEZvRRhvVnZ2dnUVZ8vidnZ2d@bt.com>, Richard Heathfield <rjh@see.sig.invalid> wrote: manu said:
unsigned long x = 65; unsigned long y = 0x3F;
y = y >> x;
If y has 65 or fewer bits (which it probably does), shifting 65 places invokes undefined behaviour. Therefore any result, or none, is admissible as far as implementation conformance is concerned.
Additional information: at least one common processor family takes the shift code modulo 32 when shifting 32 bit numbers. That's an implementation detail and perfect permitted by the standard section that Richard cited; just thought you might want to know how you ended up with the particular answer you did.
|
What particular answer did he wind up with? He most certainly did not tell us. And regardless of the undefined behavior caused by the shift itself, the program produces more undefined behavior by passing "%x" as a conversion specifier to printf() with a type other than unsigned int.
-- Jack Klein Home: LINK FAQs for comp.lang.c LINK comp.lang.c++ LINK alt.comp.lang.learn.c-c++ LINK |
| |
| | | Richard Heathfield |  |
| Posted: Thu Jul 24, 2008 12:01 am Post subject: Re: Shifting in C |  |
Jack Klein said:
| Quote: | On Wed, 23 Jul 2008 15:02:08 +0000 (UTC), roberson@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote in comp.lang.c:
|
<snip>
| Quote: | just thought you might want to know how you ended up with the particular answer you did.
What particular answer did he wind up with?
|
0x1f
| Quote: | He most certainly did not tell us.
|
Er, actually, he most certainly did. See the OP.
-- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
| |
|
|