bitshift operator problem

  • Thread starter Serve Laurijssen
  • Start date
S

Serve Laurijssen

I've been working on an old 8-bit system and came across a problem with the
<< operator

This would always yield 0:

unsigned char i;
for (i = 0; i < 4; i++)
{
unsigned char idx = 1 << i;
....
}

while this worked as expected:

unsigned char i, mask = 1;
for (i = 0; i < 4; i++)
{
unsigned char idx = mask;
....
mask = mask << 1;
}

Is there something wrong with the first version considering that this is
code for an 8-bitter?
 
S

Serve Laurijssen

Eric Sosman said:
By "yield 0" do you mean that the value of idx was
always zero in "...."? That shouldn't be so: idx should
have been 1, 2, 4, 8 on the four loop iterations. How
did you discover that idx was zero (or have I not
understood your complaint)?

That was what I meant yes. It was seen with a debugger. I'm guessing a
compiler bug then
First tell us more about your intentions, and about your
means of discovering what your code fragments are doing.

a debugger. The bits were used to set a signal and after that read a signal
from a register to check if a button was pressed.
 
F

Flash Gordon

Serve Laurijssen wrote, On 05/09/08 14:56:
That was what I meant yes. It was seen with a debugger. I'm guessing a
compiler bug then


a debugger. The bits were used to set a signal and after that read a
signal from a register to check if a button was pressed.

Did you use the value of idx? I'm guessing possibly not, or possibly it
was only assigned to what C thought of as a variable but was actually
memory mapped HW. Check that you have used 'volatile' for the
declaration/definition of anything which is mapped to HW.

I've implemented scanning a hex keypad in SW before, strobing the fours
lines checking for whether any of the relevant 4 bits are set, and I'm
guessing this is what you are doing. I was doing it because I was
writing SW to test the keypad, normally I would just use a dedicated
chip to do it.
 
S

Serve Laurijssen

Flash Gordon said:
Did you use the value of idx? I'm guessing possibly not, or possibly it
was only assigned to what C thought of as a variable but was actually
memory mapped HW. Check that you have used 'volatile' for the
declaration/definition of anything which is mapped to HW.

Ok thanks. I just wanted to know if (1<<i) was 100% correct from a C point
of view. The expression would be converted to int because of the 1 which
caused the problem. Using ints on this platform generates lots more (non
atomic) instructions and since it was called in an interrupt handler some
stuff could go wrong there. But anyway, ((unsigned char)1<<i) didnt work
either.

I've implemented scanning a hex keypad in SW before, strobing the fours
lines checking for whether any of the relevant 4 bits are set, and I'm
guessing this is what you are doing. I was doing it because I was writing
SW to test the keypad, normally I would just use a dedicated chip to do
it.

it was just part of a test program
 
W

Willem

Serve Laurijssen wrote:
) Ok thanks. I just wanted to know if (1<<i) was 100% correct from a C point
) of view. The expression would be converted to int because of the 1 which
) caused the problem. Using ints on this platform generates lots more (non
) atomic) instructions and since it was called in an interrupt handler some
) stuff could go wrong there. But anyway, ((unsigned char)1<<i) didnt work
) either.

Maybe you should check what the assembler instructions are that the
compiler generates.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
A

Ali Karaali

Alright ;

What happenes if a sign integer shifts left or right?

I mean what is the situation of sign bit.
 
A

Ali Karaali

 If E1 has a signed type and nonnegative value,
        and E1×2E2 is representable in the result type, then that is
        the resulting value; OTHERWISE, the behavior is undefined..


What is OTHERWISE?
 
A

Ali Karaali

     If `1' is negative (that is, if the left-hand operand, not
actually `1', is negative), the behavior is undefined.

Actually I would like to know what is the result of?
Was it define?

int i = 1; // i is a signed integer
i << 2;
 
C

CBFalconer

Ali Karaali wrote: **** and removed attributions - bad ****
What is OTHERWISE?

If E1 has an unsigned type or negative value, or E1*2E2 is not
representablie in the result type. :)
 
B

Ben Bacarisse

CBFalconer said:
Ali Karaali wrote: **** and removed attributions - bad ****

If E1 has an unsigned type or negative value, or E1*2E2 is not
representablie in the result type. :)

Not sure if the smiley is there just to say "yes, I know I got this
wrong, I am joking".

For the OP: (1) the odd E1x2E2 means E1 times 2 raised to the power E2
(the text version of the standard that CBFalconer uses looses the
formatting of powers). (2) The otherwise refers to those cases when
the result is not previously covered. You need to read the whole
thing, including the previous part:

3 The integer promotions are performed on each of the operands. The
type of the result is that of the promoted left operand. 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.

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."

So E2 being too big or too small (negative) is covered by 3. In all
other cases E1 << E2 is well-defined if E1 is an unsigned type. The
otherwise refers to those cases when E1 is signed and the result can't
be represented in the promoted type. Thus, on most systems you will
come across,

1 << (sizeof(int) * CHAR_BIT - 1)

is undefined.
 
B

Ben Bacarisse

Ali Karaali said:
What about;

signed char i = 1;

i << 7;

This is fine (but daft sine the result is thrown away). The shift is
performed after promoting the operands and 1 << 7 is representable as
in int (the promoted type). See my other message to the full wording.

This, however,

i = i << 7;

is likely to be a problem because the integer result of the shift
(128) probably can't be converted back to a signed char. C99 says you
get implementation-defined behaviour or an implementation-defined
signal is raised.
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top