473,624 Members | 2,027 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Strange bit shifting result with gcc - am I missing somethingobviou s?

On 32 bit linux with gcc 4.2 I get unexpected results with this code:

main()
{
int bits = 32;
printf("%d\n",( int)1 << (int)32);
printf("%d\n",( int)1 << bits);
}
The first printf gives a result of 0, the second gives 1. I checked
with sizeof() and ints are definately 32 bits in size.

I'm sure I'm missing something obvious but can someone tell me what?

Thanks

B2003
Mar 30 '08 #1
9 2249
Boltar wrote:
On 32 bit linux with gcc 4.2 I get unexpected results with this code:

main()
{
int bits = 32;
printf("%d\n",( int)1 << (int)32);
printf("%d\n",( int)1 << bits);
}
The first printf gives a result of 0, the second gives 1. I checked
with sizeof() and ints are definately 32 bits in size.

I'm sure I'm missing something obvious but can someone tell me what?

Thanks

B2003
When I compile tyour code with lcc-win I get:

Warning tshift.c: 2 no type specified. Defaulting to int

The prototype for main is:
int main(void)

Warning tshift.c: 5 missing prototype for printf

You did not include <stdio.h>

Warning tshift.c: 5 shift by 32 is undefined

The number of bits shifted is greater than sizeof(int)*CHA R_BIT
This is undefined!

The result of running the program is:

16777216
1

If I turn optimizations ON I get:
16777216
1024

The result of shifting more than sizeof(int)*CHA R_BIT positions
is NOT defined by the language. It is an illegal expression.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Mar 30 '08 #2
Boltar wrote:
On 30 Mar, 21:37, jacob navia <ja...@nospam.c omwrote:
>The result of shifting more than sizeof(int)*CHA R_BIT positions
is NOT defined by the language. It is an illegal expression.

It isn't? Thats bloody annoying since that means i'll have to do a
specific check for the bit shift count being than the size of the
type being shifted.
Actually, you need to check for >=, not just >. And
with signed integers, you need to be sure the value being
shifted is non-negative and small enough that no 1's are
propagated into the sign position.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Mar 30 '08 #3

"jacob navia" <ja***@nospam.c omwrote in message
news:fs******** **@aioe.org...
Boltar wrote:
>On 32 bit linux with gcc 4.2 I get unexpected results with this code:

main()
{
int bits = 32;
printf("%d\n",( int)1 << (int)32);
printf("%d\n",( int)1 << bits);
}
The first printf gives a result of 0, the second gives 1. I checked
with sizeof() and ints are definately 32 bits in size.

I'm sure I'm missing something obvious but can someone tell me what?
When I compile tyour code with lcc-win I get:
Warning tshift.c: 5 shift by 32 is undefined

The number of bits shifted is greater than sizeof(int)*CHA R_BIT
This is undefined!
OK, but the following code from lccwin does not appear to set up the shift
count in cl register. So you don't even attempt to shift by 32, but by an
unknown value in cl (presumably 24)?

; 6 printf("%d\n",( int)1 << (int)32);
.line 6
movl $1,%edi
movl $32,%esi
sall %cl,%edi

On the x86 at least, shifting a 32-bit register left by 32 is anyway a
no-operation (the register is unchanged).

So the OP should not rely on 32+ bit left-shifts working as he expects.

--
Bart

Mar 30 '08 #4
Bartc wrote:
OK, but the following code from lccwin does not appear to set up the shift
count in cl register. So you don't even attempt to shift by 32, but by an
unknown value in cl (presumably 24)?

; 6 printf("%d\n",( int)1 << (int)32);
.line 6
movl $1,%edi
movl $32,%esi
sall %cl,%edi

On the x86 at least, shifting a 32-bit register left by 32 is anyway a
no-operation (the register is unchanged).

So the OP should not rely on 32+ bit left-shifts working as he expects.
Surely not. Things go as follows:

lcc-win discovers that we have a shift operation with
two immediate constants. This should be done at
compile time to make the generated program more efficient.

Then it discovers that one of the constants is too big
and generates a warning. Apparently, when making this
optimizations it doesn't set cl.

If you change the program to
5 printf("%d\n",( int)1 << (int)31);
.line 5
pushl $-2147483648 // Shift done at compile time
pushl $_$2
call _printf
addl $8,%esp

You see?

Now, it can be argued that this is a bug. True.

I have changed this now so that it will do the shift at compile time,
returning whatever the result is at compile time (1) anyway.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Mar 30 '08 #5
Boltar <bo********@yah oo.co.ukwrote:
On 32 bit linux with gcc 4.2 I get unexpected results with this code:

main()
{
int bits = 32;
printf("%d\n",( int)1 << (int)32);
printf("%d\n",( int)1 << bits);
}
The first printf gives a result of 0, the second gives 1. I checked
with sizeof() and ints are definately 32 bits in size.

I'm sure I'm missing something obvious but can someone tell me what?
That the shift count must be *less than* the number of bits in the
operand or you get undefined behavior.

-Larry Jones

Please tell me I'm adopted. -- Calvin
Mar 30 '08 #6
Boltar <bo********@yah oo.co.ukwrote:
>
It isn't? Thats bloody annoying since that means i'll have to do a
specific check for the bit shift count being than the size of the
type being shifted.
The theory is it's better to have to have an explicit check for the
relatively small amount of code that needs it than to have the compiler
always generate for the vast majority of code that doesn't need it.

-Larry Jones

OK, what's the NEXT amendment say? I know it's in here someplace. -- Calvin
Mar 31 '08 #7
Bartc <bc@freeuk.comw rote:
>
On the x86 at least, shifting a 32-bit register left by 32 is anyway a
no-operation (the register is unchanged).
On the contrary, different processors in the x86 family behave
differently. Some only look at the bottom 5 bits of the count (so a
shift count of 32 is interpreted as 0 and 33 as 1) but others look at
the entire value (so a shift count of 32 or greater zeros the register).

-Larry Jones

You're just trying to get RID of me, aren't you? -- Calvin
Mar 31 '08 #8
>OK, but the following code from lccwin does not appear to set up the shift
>count in cl register. So you don't even attempt to shift by 32, but by an
unknown value in cl (presumably 24)?

; 6 printf("%d\n",( int)1 << (int)32);
.line 6
movl $1,%edi
movl $32,%esi
sall %cl,%edi

On the x86 at least, shifting a 32-bit register left by 32 is anyway a
no-operation (the register is unchanged).

So the OP should not rely on 32+ bit left-shifts working as he expects.

Surely not. Things go as follows:

lcc-win discovers that we have a shift operation with
two immediate constants. This should be done at
compile time to make the generated program more efficient.

Then it discovers that one of the constants is too big
and generates a warning. Apparently, when making this
optimization s it doesn't set cl.
This is not a bug. 1 << 32 invokes the wrath of undefined behavior.
Since no possible answers are wrong, you might as well get one
quickly, even if it's random crap.
>If you change the program to
5 printf("%d\n",( int)1 << (int)31);
.line 5
pushl $-2147483648 // Shift done at compile time
pushl $_$2
call _printf
addl $8,%esp

You see?

Now, it can be argued that this is a bug. True.
I'll argue that the wording of the error message is a
quality-of-implementation issue.
>I have changed this now so that it will do the shift at compile time,
returning whatever the result is at compile time (1) anyway.
Mar 31 '08 #9
jacob navia:
The number of bits shifted is greater than sizeof(int)*CHA R_BIT
This is undefined!

Don't forget about systems that have padding bits within their integer
types. On such systems, sizeof(some int type)*CHAR_BIT will yield a
value which is larger than the amount of value representationa l bits
in that type.
Apr 1 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
8728
by: GGG | last post by:
Noticed something odd in the way bit shifting was working today. As far as I have ever heard, shifting will shift in zeros(signed ints aside) However I foudn something odd when I am shifting exactly the number of bits in a value... i.e. uint32_t x = 5;
11
5438
by: vj | last post by:
Hello group, I am working on a compression tool and saw this puzzling bit shit behaviour on a VC++6.0 compiler. #include <iostream> using namespace std; typedef unsigned char uchar; #define NBITS(x) ((uchar)(~0u<<sizeof(0u)*8-(x) >>sizeof(0u)*8-(x))) // NBITS forms a byte containing specified number of bits turned on.
18
4711
by: richard_l | last post by:
Hello All, I am writing an application which receives a word which is a bitmap. I have created a word typedef which contains a bitfield defining each bit. however, I was wondering however if it would be better to write a macro to access each bit instead of the bitfield. I have read the C-FAQ on bit fields, but was wondering if there were any advantages/disadvantages to using bit shifting. To my mind I think using bitfields are more...
10
10687
by: krunalb | last post by:
Hi, I am trying to shift unsigned long long value by 64 bits and this is what i get #include <stdio.h> int main() { unsigned short shiftby= 64;
20
2501
by: Charles Sullivan | last post by:
I understand different processor hardware may store the bits in a byte in different order. Does it make a difference in C insofar as bit-shifting unsigned char variables is concerned? E.g, if I have unsigned char x = 1; is it always true that (x << 1) == 2 (x << 2) == 4 etc?
9
1689
by: Dave | last post by:
Hi guys, I have just set up a duplicate server running: apache 2.54, mysql 5.04 and php 5.04 This is the same setup as as the server we are using now, apart from the hardware inside. I have copied across the database and website, with exact same permissions as the first server. The problem is that part of the php code is executing but others
16
1550
by: lak | last post by:
i know left and right shift normally,but i cant know what happens if it is negative. for example int x=-2; x<<=1;//what happens here
3
5542
by: Madhur | last post by:
I would like to know the best efficient way to shift a flat buffer by say 4bits. for exaple if the flat buffer is 0x62 0x48 0x23 .... then the result should be 0x06 0x24 0x82 0x3.....
12
2251
by: Boltar | last post by:
I seem to be having yet more wierd issue with bit shifting. It seems the following code doesnt do anything under gcc (ie it returns -1 as both results). Anyone know why? Is it another language definition or CPU issue? main() { printf("%d\n",(int)0xFFFFFFFF >1); printf("%d\n",(int)-1 >1); }
0
8236
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
8335
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8475
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6110
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4079
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4174
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2606
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1785
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1482
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.