473,883 Members | 2,621 Online

# Left shift

Hi,

in the header of my class I've a constant

static const int a = ( 1 << 32 ) - 1;

When compiling the code, g++ issues the warning
"warning: left shift count >= width of type"

Why? And how can I get rid of that?

Thank you.
Chris
Aug 23 '06
56 15370

Victor Bazarov wrote:
Whatever conclusions you're trying to make from whatever knowledge you
possess about the hardware are nonconsequentia l; the Standard says that
the behaviour of the program in which the right operand of the shift
operator is negative or greater than or equal to the length in bits of
the promoted left operand is *undefined*. It can be 0, it can be 1, or
(and you know the drill, repeat after me) it can make demons fly out of
Is the behaviour also undefined if you shifted by 1 bit 32 times? Are
the two equivalent?

In that case ((1 << 16) << 16) would be fully defined as long as
sizeof(int) 16.

I assume, by the way, that it is perfectly defined behaviour to
right-shift bits off the end because that I do regularly, eg
right-shift 0x1234 >8 should give me 0x12. (If you're not allowed to
do that there is something horribly wrong with the standard).

Aug 25 '06 #11
Earl Purple wrote:
Victor Bazarov wrote:
>Whatever conclusions you're trying to make from whatever knowledge
you possess about the hardware are nonconsequentia l; the Standard
says that the behaviour of the program in which the right operand of
the shift operator is negative or greater than or equal to the
length in bits of the promoted left operand is *undefined*. It can
be 0, it can be 1, or (and you know the drill, repeat after me) it
can make demons fly out of your nose.

Is the behaviour also undefined if you shifted by 1 bit 32 times? Are
the two equivalent?
No, they are not equivalent. Shifting by 1 bit is well-defined. No
matter how many times you do it.
In that case ((1 << 16) << 16) would be fully defined as long as
sizeof(int) 16.
Correct.
I assume, by the way, that it is perfectly defined behaviour to
right-shift bits off the end because that I do regularly, eg
right-shift 0x1234 >8 should give me 0x12. (If you're not allowed to
do that there is something horribly wrong with the standard).
It's well-defined. Get a copy of the Standard to check.

V
--
Aug 25 '06 #12

"Earl Purple" <ea********@gma il.comskrev i meddelandet
news:11******** **************@ i3g2000cwc.goog legroups.com...
>
Victor Bazarov wrote:
>Whatever conclusions you're trying to make from whatever knowledge
you
possess about the hardware are nonconsequentia l; the Standard says
that
the behaviour of the program in which the right operand of the
shift
operator is negative or greater than or equal to the length in bits
of
the promoted left operand is *undefined*. It can be 0, it can be
1, or
(and you know the drill, repeat after me) it can make demons fly
out of

Is the behaviour also undefined if you shifted by 1 bit 32 times?
Are
the two equivalent?

In that case ((1 << 16) << 16) would be fully defined as long as
sizeof(int) 16.
The restriction in the standard is there because of the underlying
hardware.

We expect the compiler to be able to use the shift instructions of the
CPU. The problem is that some hardware will actually perform the long
shift (with a zero result), while others will do it modulo register
size. Others might refuse altogether.

With the popular x86 family, the behaviour has changed between
generations, which makes it hard for the compiler to compensate.

So, the C++ standard says that a shift works as expected as long as
the shift count is smaller than the integer type. If it is larger we
don't know, that's up to the underlying hardware.
Aug 25 '06 #13
Marcus Kwok wrote:
>
At this point, since an int is 8 bits, we can see why we can only shift
a maximum of 7. When it gets to (1 << 8), what should it do? Shift the
1 completely out of the number? Or leave it where it is? I'm not sure
but this is probably one of {undefined, unspecified,
implementation-defined}.
Undefined behavior. On the Intel i860, there is only enough bits
in the shift instruction to encode 31 places. If you do 32, it
only stuffs the low order bits and you get NOTHING. Believe me
the @&\$@ X11 Server code relied on that yielding a zero not the
original operand. Had to fix it in a dozen places.

Aug 26 '06 #14
In article <44************ ***********@new s.newshosting.c om>,
ro*@spamcop.net says...

[ ... ]
Undefined behavior. On the Intel i860, there is only enough bits
in the shift instruction to encode 31 places. If you do 32, it
only stuffs the low order bits and you get NOTHING. Believe me
the @&\$@ X11 Server code relied on that yielding a zero not the
original operand. Had to fix it in a dozen places.
The x86 allows you to encode more if you want to, but recent iterations
of the processor mask it to 5 bits before doing the shift.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 26 '06 #15
Jerry Coffin <jc*****@taeus. comwrote:
>ro*@spamcop.ne t says...
>Undefined behavior. On the Intel i860, there is only enough bits
in the shift instruction to encode 31 places. If you do 32, it
only stuffs the low order bits and you get NOTHING. Believe me
the @&\$@ X11 Server code relied on that yielding a zero not the
original operand. Had to fix it in a dozen places.
>The x86 allows you to encode more if you want to, but recent iterations
of the processor mask it to 5 bits before doing the shift.
And I still say for in the code fragment posted, no left shift
instruction will ever be emitted by the compiler, so such details are
quite possibly irrelevant.

Steve
Aug 26 '06 #16
In article <ec**********@b lue.rahul.net>, sp*****@speedym ail.org says...

[ ... ]
And I still say for in the code fragment posted, no left shift
instruction will ever be emitted by the compiler, so such details are
quite possibly irrelevant.
This seems almost self-contradictory. If you could be certain the
compiler wouldn't emit a left-shift instruction, then such details would
be definitely irrelevant. The only way they may be relevant is if the
compiler might emit the instruction -- which I'd say is correct for at
least a few compilers.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Aug 26 '06 #17
Jerry Coffin <jc*****@taeus. comwrote:
sp*****@speedym ail.org says...
>And I still say for in the code fragment posted, no left shift
instruction will ever be emitted by the compiler, so such details are
quite possibly irrelevant.
This seems almost self-contradictory. If you could be certain
the compiler wouldn't emit a left-shift instruction, then such
details would be definitely irrelevant. The only way they may
be relevant is if the compiler might emit the instruction --
which I'd say is correct for at least a few compilers.
That is why I said "possibly irrelevant". "Intuitivel y, constant
expressions are simple expressions that can be evaluated by the
compiler before the program is linked [9.1] and starts to run."
(Stroustrap, C.5) To me it's unintuitive (but not incorrect) that
the compiler would not reduce the expression.

And actually, if the constant expression reduces to zero and is
assigned to a pointer, it's probably incorrect for the compiler
not to reduce it; but maybe those more expert than I might have
an opinion on this.

Steve
Aug 26 '06 #18
Following up to myself:

Steve Pope <sp*****@speedy mail.orgwrote:
>Jerry Coffin <jc*****@taeus. comwrote:
>sp*****@speedym ail.org says...
>>And I still say for in the code fragment posted, no left shift
instruction will ever be emitted by the compiler [..]
>This seems almost self-contradictory. If you could be certain
the compiler wouldn't emit a left-shift instruction, then such
details would be definitely irrelevant. The only way they may
be relevant is if the compiler might emit the instruction --
which I'd say is correct for at least a few compilers.
>That is why I said "possibly irrelevant". "Intuitivel y, constant
expressions are simple expressions that can be evaluated by the
compiler before the program is linked [9.1] and starts to run."
(Stroustrap, C.5) To me it's unintuitive (but not incorrect) that
the compiler would not reduce the expression.
>And actually, if the constant expression reduces to zero and is
assigned to a pointer, it's probably incorrect for the compiler
not to reduce it; but maybe those more expert than I might have
an opinion on this.
In fact, the following compiles (gcc):

int foo() {
int *pi;
pi = 1 << 100;
}

It seems to me that any approach that did not perform the
left shift until runtime would not be a correct implementation.

(Although there are some screwy possibilties, such as only
reducing the constant expression at compile time when it's
being assigned to a pointer; or reducing if it reduces to zero,
and issuing code for it otherwise; but I think these possibilities
are very highly remote.)

Steve
Aug 27 '06 #19

"Steve Pope" <sp*****@speedy mail.orgskrev i meddelandet
news:ec******** **@blue.rahul.n et...
Jerry Coffin <jc*****@taeus. comwrote:
>sp*****@speedym ail.org says...
>>And I still say for in the code fragment posted, no left shift
instruction will ever be emitted by the compiler, so such details
are
quite possibly irrelevant.
>This seems almost self-contradictory. If you could be certain
the compiler wouldn't emit a left-shift instruction, then such
details would be definitely irrelevant. The only way they may
be relevant is if the compiler might emit the instruction --
which I'd say is correct for at least a few compilers.

That is why I said "possibly irrelevant". "Intuitivel y, constant
expressions are simple expressions that can be evaluated by the
compiler before the program is linked [9.1] and starts to run."
(Stroustrap, C.5) To me it's unintuitive (but not incorrect) that
the compiler would not reduce the expression.

And actually, if the constant expression reduces to zero and is
assigned to a pointer, it's probably incorrect for the compiler
not to reduce it; but maybe those more expert than I might have
an opinion on this.
Do you mean that compile time constant expressions should be evaluated
differently than non-constant expressions? Shouldn't we expect the
same result?
To be more technical, the standard doesn't talk about compilers at
all - we could very well have an interpreter, or some other kind of
translator. And *if* a compiler does a compile time evaluation, is it
not supposed to use the hardware instructions itself, internally?