0

I'm working with CodeVisionAVR Evaluation V2.05.0 which use C Compiler Reference.I met a problem when I tried this code:

unsigned int n;
long int data;
data|=(1<<n);

the problem is when n is Greater than 15 the value of data does not change. Although when I try:

data|=(1<<16);

the result is correct. any help pleas.

4 Answers4

0

In your code, the type of 1 is (as always) int. So, if sizeof (int) is smaller than sizeof (long), it stands to reason that you can't shift an int over all the bits in a long.

The solution is of course to use an (unsigned) long constant:

data |= 1UL << n;

I made it unsigned since unsigned integers are better suited for bitwise operators. The type of the literal 1UL is unsigned long. I find using suffixes nicer than casting, since it's way shorter and part of the literal itself, rather than having a literal of the wrong type and casting it.

Many people seem to expect that in an expression such as:

unsigned long long veryBig = 1 << 35; /* BAD CODE */

the right-hand side should somehow magically adapt to the "needs" of the left-hand side, and thus become of type unsigned long long (which I just assume has at least 35 bits, this is of course not portable but it's concise). That does not happen, C doesn't work like that. The expression is evaluated, then it's converted (if necessary) to the type on the left for the assignment to work.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

If sizeof(int)==2 then 1<<n is of type int. And 1<<16 == 0. Thus data is not changed.

Matt
  • 13,674
  • 1
  • 18
  • 27
  • 16-bit int doesn't necessarily mean that `sizeof(int) == 2`, because `CHAR_BIT` can be 16 – phuclv Mar 03 '15 at 14:19
  • @LưuVĩnhPhúc What architecture? Won't be `sizeof(int)<=2` anyway? – Matt Mar 03 '15 at 14:34
  • There's no limit in C and C++ standard about any types' sizes except their ranges and `sizeof(char) == 1`. Don't you see `sizeof(int) == 4` which is larger than 2 on most architectures? http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char – phuclv Mar 03 '15 at 14:37
  • Some more examples [here](http://stackoverflow.com/questions/6971886/exotic-architectures-the-standards-committees-care-about) – phuclv Mar 03 '15 at 14:37
  • @LưuVĩnhPhúc OK, I got it. But this one seems not to be such a case, and writing `sizeof(int)==2` is shorter than 'int type is 16-bits long'. – Matt Mar 03 '15 at 14:41
0

Probably because int is 16 bits. When you use integer literals the compiler can work out that the result is larger than fits in an int, and will optimize the whole shift-operation away, but when you use a variable, the compiler can't do that because it doesn't know the value of n.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

i want to thank everyone, by your answer I really understood the problem which is 1 in (1<<n) is integer with size 2 bytes. i fixed the problem by let 1 be unsigned long (1UL<<n). this is first question for me and you are awesome guys. thank you and I'm sorry for my bad english.