Regarding Left shift operator in embedded processor

Respected Experts,

Iam RaviKumar.N, Iam using Intel-386EX embedded processor for one of my application also Iam using a cross compiler for the execution of my code. I have a query regarding left shift operator.

Consider the following variables: 1) unsigned char a = 2; 2) unsigned char b = 3; 3) unsigned short c;

Consider the following expression:

c = (unsigned short)(( a

Reply to
Ravi kumar.N
Loading thread data ...

consider this:

unsigned char a, b; unsigned short c;

a = 1; b = a

Reply to
karol kluska

The C standard specifies how implicit type coercion will operate, but it is best not to rely on standards compliance. Instead write your assignment as:

c = ( ( unsigned short ) a

Reply to
WhoAmI

This might be better directed to one of the C language news groups but here goes.

Because of C's implicit promotion a and b are first promoted to int. You then left shift an int sized quantity (32 bits on a 386SX? or 16?), then or that with another int sized quantity. That result is then cast to an unsigned short and (if the sizeof(unsigned short) is smaller than sizeof(int)) truncated. Therefore you don't shift an 8-bit value.

The compiler is free to translate that into a sequence involving only 8 bit values provided it gets the same result as the above.

Robert

Reply to
R Adsett

Yes it is valid. What happens is that "a" gets promoted from unsigned char to int before it is shifted, so "a

Reply to
Robert Scott

Reply to
Grant Edwards

Maybe. The cast is useless, and should be omitted (as should most casts) because it serves only to hide errors here.

The first thing that is done with 'a' is to extend it to an int in order to operate on it. The shift on that is legitimate, provided it never becomes negative. This requires that 'a' not have a high order bit set, which is so in your example, but not in general.

The correct place for a cast is on 'a', to avoid the conversion to int.

c = ((unsigned)a

Reply to
CBFalconer

I didn't think a cast from unsigned to a larger signed type would sign extend. Am I remembering incorrectly?

Robert

Reply to
R Adsett

Please leave a blank line between the quotes and your reply, so we can detect it.

Nothing to do with it here. If a has a high order bit, the last of the 8 shifts moves that into the sign position of an integer (assumed 16 bits, which is all that the standard guarantees). At that point it is something (beyond the range of integer), and behavior is no longer standardized. Remember a left shift means multiply by 2.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

ANSI Standard C promotes 8-bit chars to short integers for all computations. So a

Reply to
Tim Wescott

On Wed, 12 Jan 2005 16:08:52 -0800, Tim Wescott wrote in comp.arch.embedded:

No, you are completely wrong. Standard C requires that any type shorted than an int gets promoted to either signed or unsigned int in expressions. Not short int, plain old ordinary int. If the OP is using a 16-bit compiler, short int and int happen to have the same representation. On the other hand, if he is using a 32-bit compiler, that unsigned char is promoted to a full 32 bit signed int before the shift operation happens.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply to
Jack Klein

On Wed, 12 Jan 2005 15:41:58 GMT, "WhoAmI" wrote in comp.arch.embedded:

You may be telling the compiler what you want to happen, but if it actually does so it is not a conforming C compiler.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
Reply to
Jack Klein

On 12 Jan 2005 16:03:15 GMT, Grant Edwards wrote in comp.arch.embedded:

Reply to
Jack Klein

bits in an int is a compiler value, not a CPU. A 16 bit CPU could have a compiler with 32 ints. OR old 16 bit compilers are still 16 bits on a 32 bit CPU

Reply to
Neil Kurzman

I'd argue about the "totally" part, but not the nature of my mistake -- having been reminded by another poster on this I have already slapped my forehead and said "doh!".

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Reply to
Tim Wescott

... snip ...

No, the promotion is into an integer.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
     USE worldnet address!
Reply to
CBFalconer

well... I was right about one thing... I wrote: I know nothing about compilers ;-)

but then - I "sensed" the problem correctly and for my own wellbeing I know how to protect myself (and my code) against problems like that ;-) but it's good to know such things "for sure"...

Reply to
karol kluska

Oops, I guess I've gotten used to the colour distinctions in my current newsreader.

Ah, sign of the end result not the intermediate cast, different issue all together. (Forest remember than damn forest!)

Robert

Reply to
R Adsett

You are correct. There is no sign to extend.

Reply to
toby

Not for the vast majority of meanings the word "valid" in that sentence could have, no.

On the typical platform, shifting a byte left by 8 yields a constant zero --- if that was what you wanted, you could just have spelled out that zero.

The correct way of doing what you wanted would be (with some extraneous parentheses

(((unsigned short) a)

Reply to
Hans-Bernhard Broeker

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.