L
lak
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
it is negative.
for example
int x=-2;
x<<=1;//what happens here
lak said: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
cat test_shift.c
k is -1 (ffffffff)gcc -Wall -o test_shift test_shift.c && ./test_shift
lak said: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
Richard Bos said:That is correct: you cannot know that.
From paragraph 6.5.7 in the ISO C Standard:
# 4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
# bits are filled with zeros. If E1 has an unsigned type, the value of
# the result is E1 x 2 E2 ,reduced modulo one more than the maximum
# value representable in the result type. If E1 has a signed type and
# nonnegative value, and E1 x 2 E2 is representable in the result
# type, then that is the resulting value; otherwise, the behavior is
# undefined. ^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^
Note the under^^^lined bit. Since in your case x is neither an unsigned
integer, nor a signed integer with a positive value, the behaviour of
your code is undefined; and this means that, as far as ISO C is
concerned, you cannot know what happens. (It may be possible to discover
what happens on a particular computer using a particular compiler with
particular compilation settings, but I advise against it; on the next
system, or even on the next level of optimisation, the result can easily
be different.)
Pietro said:nothing different from usual.. the bit representation of -2 is shifted
one bit to the left...
However, if you expected x <<= 1 to be equivalent to x += x, as would
"normally" be the case on regular 2s-complement machines, you might
as well write the latter.
Pietro said:Umh, I have to apologize.. my sentence is actually incorrect.
That's true for right-shifting, while for left-shifting a
negative left-hand operand invokes UB
Umh, I have to apologize.. my sentence is actually incorrect. That's
true for right-shifting, while for left-shifting a negative left-hand
operand invokes UB
Richard is correct.
However, if you expected x <<= 1 to be equivalent to x += x, as would
"normally" be the case on regular 2s-complement machines, you might as well
write the latter.
Charlie Gordon wrote:
[... bit-shifting negative numbers ...]
However, if you expected x <<= 1 to be equivalent to x += x, as would
"normally" be the case on regular 2s-complement machines, you might
as well write the latter.
Okay, nit-pick time related to UB.
Why doesn't the statement:
x += x;
violate 6.5p2:
Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be read
only to determine the value to be stored.
Yes, I see that footnote 71 says that "i = i + 1" is allowed by the
paragraph, but why is the "x" on the right of "+=" not violating the
"shall be read only to determine the value to be stored"? How is
this different from "y = x + x++;" in the use of "x"?
Obviously, something like "x += x;" must be allowed, but what is it
about 6.5p2 that allows it?
Kenneth Brody said:Charlie Gordon wrote:
[... bit-shifting negative numbers ...]However, if you expected x <<= 1 to be equivalent to x += x, as would
"normally" be the case on regular 2s-complement machines, you might
as well write the latter.
Okay, nit-pick time related to UB.
Why doesn't the statement:
x += x;
violate 6.5p2:
Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be read
only to determine the value to be stored.
Yes, I see that footnote 71 says that "i = i + 1" is allowed by the
paragraph, but why is the "x" on the right of "+=" not violating the
"shall be read only to determine the value to be stored"? How is
this different from "y = x + x++;" in the use of "x"?
Obviously, something like "x += x;" must be allowed, but what is it
about 6.5p2 that allows it?
I am afraid I don't understand shifts anymore. I suppose(d) that onRichard said:That is correct: you cannot know that.
From paragraph 6.5.7 in the ISO C Standard:
# 4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
# bits are filled with zeros. If E1 has an unsigned type, the value of
# the result is E1 x 2 E2 ,reduced modulo one more than the maximum
# value representable in the result type. If E1 has a signed type and
# nonnegative value, and E1 x 2 E2 is representable in the result
# type, then that is the resulting value; otherwise, the behavior is
# undefined. ^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^
Note the under^^^lined bit. Since in your case x is neither an unsigned
integer, nor a signed integer with a positive value, the behaviour of
your code is undefined; and this means that, as far as ISO C is
concerned, you cannot know what happens. (It may be possible to discover
what happens on a particular computer using a particular compiler with
particular compilation settings, but I advise against it; on the next
system, or even on the next level of optimisation, the result can easily
be different.)
Richard
Ark Khasin said:I am afraid I don't understand shifts anymore. I suppose(d) that on 32-bit
machine
insigned x, y;
y = 32U; //where the compiler doesn't see it
(x<<y)==0U && (x>>y)==0U
All ARM compilers I've seen, the effective calculation is
x << (y & 31U) and x << (y & 31U)
(because that's how the CPU instructions work)
Is this compliant?
Thanks. I should have known better indeed.Charlie said:C99 6.5.7p3 also says: If the value of the right operand is negative or is
greater than or equal to the width of the promoted left operand, the
behavior is undefined. So shifting a 32-bit integer by 32 invokes undefined
behaviour. That covers any harware behaviour whatsoever.
If you really want that, you need to split the operation:
(x << 16) << 16 == 0 && (x >> 16) >> 16 == 0
x is modified only once, and it is only read to determine theWhy doesn't the statement:
x += x;
violate 6.5p2:
Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be read
only to determine the value to be stored.
Yes, I see that footnote 71 says that "i = i + 1" is allowed by the
paragraph, but why is the "x" on the right of "+=" not violating the
"shall be read only to determine the value to be stored"? How is
this different from "y = x + x++;" in the use of "x"?
Obviously, something like "x += x;" must be allowed, but what is it
about 6.5p2 that allows it?
Kenneth Brody said:Charlie Gordon wrote:
[... bit-shifting negative numbers ...]However, if you expected x <<= 1 to be equivalent to x += x, as would
"normally" be the case on regular 2s-complement machines, you might
as well write the latter.
Okay, nit-pick time related to UB.
Why doesn't the statement:
x += x;
violate 6.5p2:
Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be read
only to determine the value to be stored.
Yes, I see that footnote 71 says that "i = i + 1" is allowed by the
paragraph, but why is the "x" on the right of "+=" not violating the
"shall be read only to determine the value to be stored"? How is
this different from "y = x + x++;" in the use of "x"?
lak said: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
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.