Unix Technical Forum

Re: shifting curiosity

This is a discussion on Re: shifting curiosity within the mailing.openbsd.tech forums, part of the OpenBSD category; --> On Thu, 16 Jun 2005, Moritz Grimm wrote: > Hi, > > > today, I came across an idiosyncrasy ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 07:54 AM
Otto Moerbeek
 
Posts: n/a
Default Re: shifting curiosity

On Thu, 16 Jun 2005, Moritz Grimm wrote:

> Hi,
>
>
> today, I came across an idiosyncrasy wrt shifting in C/C++, at least with gcc
> and g++ on OpenBSD/i386.
>
> The following snippet demonstrates it in a form that also occurs quite a few
> times similarily in OpenBSD source code, e.g. in src/usr.sbin/bgpctl/parser.c
> and various other places (each with more or less likelihood of ``bits'' ever
> being 0):
>
> {
> unsigned int mask1, mask2;
> int bits;
>
> bits = 0;
>
> mask1 = 0xffffffff << (32 - bits);
> mask2 = (unsigned long long)0xffffffff << (32 - bits);
>
> [...]
> }
>
> mask1 and mask2 are not the same. The value of mask1 is 0xffffffff, as if it
> were left-shifted by 0, while mask2 is 0. Concerning prefix lengths of CIDR
> network numbers, the latter is clearly what we want, so that 0.0.0.0/0 doesn't
> break (I need this in a different context, which made me stumble over this in
> every case, not only when dealing with an actual 0.0.0.0/0 network.)
>
> The reason for this seems that even without optimization, the amount of bits
> to shift is mod'ed with the amount of bits in the type the shifting is done
> with - 32 % 32 = 0, ergo no shifting is being done.


A shift of an amount larger than the size of the expression in bits is
undefined. In practise the result depends on compiler and/or CPU.

In the first expression, both operands are int, so the result is
undefined. In the seconds expression, the left hand operand is
unsigned long long, so the shift is well-defined.

I don't know if the variable bits in the expression in
bgpctl/parser.c:520 can assume the value 0, bit if so, it looks like a
bug.

> My solution is to cast the unshifted mask to 64bit and let the
> casting-back-to-32bit take care of making the 1s disappear for good.


That is safe, another possibility would be something like

value = bits == 0 ? 0 : (mask << (32 - bits));
>
> What I am curious about is whether all of this is intended behavior, and why
> (I find it strange) - other than that, please consider this as a general FYI,
> as this *might* be a problem in some places in OpenBSD (userland mostly, I
> suppose).


-Otto

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 09:19 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com