How does the following code work

Started by
16 comments, last by me22 18 years, 4 months ago
Hi, I am wondering how the code works here. How does the OS see x in this case ?

 
unsigned char x = 260;

        x <<= 2;
        x &= 0XF;
        x = !x;

Thanks
The more applications I write, more I find out how less I know
Advertisement
This code looks so much artificial, that I assume it is either a joke or else a test.

However, x is an unsigned char, and hence could represent numbers inbetween 0 and 255 inclusive. Assigning 260 is hence already a mistake. I don't know if the language specification defines what has to happen in such cases. I assume that after assignment x has the value 4. That is shifted 2 digits to the left, what would yield in 16. That is bitwise ANDed with 15, what would yield in 0. And that is logically negated, what would yield in true. Don't know what internal representation the compiler will use for true, since all values different from 0 are interpreted at true. Maybe it is all 1's (say 255 as an unsigned char) or just 1.

BTW: The OS in its own sense doesn't "see" x anyway until your code is part of the OS software, and I would wonder if it is so.

Summary: The code doesn't really "works". It is erroneous and possibly compiler dependent.
Well the code definitely works and I want to know how it works. There is no joke and please refrain from making such statements unless you really know what you are saying.

Anyway in order to learn I am asking this question. I tried it in GCC and this is what I see x as in the debugger :-

Breakpoint 2, main () at test2.cpp:20
unsigned char 20 => x = 4 '\004
x <<= 2 gives x = 16 '\020'
x &= 0xf gives x = 0 '\0'
x = !x gives x = 1 '\001'

But I am not sure how exactly it works.

Thanks


The more applications I write, more I find out how less I know
Well i'm pretty sure the compiler will truncate x = 260 and after the truncation you'll be left with x equal to 4.

unsigned char is one byte and you've got 260 which is 100000100 in binary since one byte represents 8 bits a truncation will leave you with 00000100 which is 4, then you shift 4 to the left twice, 16, then you and 16 with 15, resulting in zero and the not of zero is one.

The code "works" but you realy shouldn't be assigning numbers to data types that can't store them.
Quote:Original post by CRACK123
unsigned char 20 => x = 4 '\004
x <<= 2 gives x = 16 '\020'
x &= 0xf gives x = 0 '\0'
x = !x gives x = 1 '\001'

Hence it does what I said. If you want to know why exactly here it is:

260 in decimal number system (say with base 10) is the same as 0100000100 in dual number system (say with base 2). Since unsigned char could hold only 8 bits (bits stands shortly for "binary digit") it becomes assigned the 8 lowest bits of that number, what is 00000100 in binary or 4 in decimal.

The <<= does shifting the number 2 digits to the left, filling in zeros in the "free digits" at the right. The binary 00000100 becomes so 00010000, what is equivalent to decimal 16.

The &= does a bitwise AND operation. It results in a 1 only if both belonging bits are 1, else it results in a 0. So here
00010000 binary for current x
00001111 binary for constant decimal 15
--------
00000000 binary for result, since for each digit at least one 0 is in the arguments.

The logical operator ! inverts its argument: false becomes true and true becomes false. Since the current value of x is 0 and 0 is interpreted as logical false, its inversion becomes true. That is represented by the decimal value 1. (As already said, _all_ values besides 0 are interpreted as true.)



BTW: I said:
Quote:me
This code looks so much artificial, that I assume it is either a joke or else a test.

You see, I have not stated it being a joke, I've stated _an assumption_, and furthurmore I also said "or else a test". However, I excuse me if I have hurt your feelings.
I'll add comments step-by-stepx <<= 2;   // shift x left by 2 bits// This is the same as saying x = x * 4;x &= 0XF;  // x = x AND 15// This finds what the remainder would be if you divided x by 16x = !x;    // x = NOT x// If there was a remainder, then set x to 0, otherwise set x to 1



Conclusion:
x is set to true if and only if bits two to five are all zero
x = !(x &0x3C);
Quote:Original post by Gorwooken
Well i'm pretty sure the compiler will truncate x = 260 and after the truncation you'll be left with x equal to 4.

unsigned char is one byte and you've got 260 which is 100000100 in binary since one byte represents 8 bits a truncation will leave you with 00000100 which is 4, then you shift 4 to the left twice, 16, then you and 16 with 15, resulting in zero and the not of zero is one.

The code "works" but you realy shouldn't be assigning numbers to data types that can't store them.


Yes I know, I was merely asking what it does as it was asked this in one of the interviews I went to. I merely wanted to know how it works.

I got a little irritated that someone here "assumed" the post to be a joke.
The more applications I write, more I find out how less I know
It's compiler dependent.
Quote:Original post by CRACK123
Yes I know, I was merely asking what it does as it was asked this in one of the interviews I went to. I merely wanted to know how it works.

I got a little irritated that someone here "assumed" the post to be a joke.

"... or else a test." It was obviously a test. So I don't understand your displeasure.

However, the code actually does something, but only due to doubtful acceptance by the compiler (EDIT: better: the language). As several writers have stated, the assignment of a number outside the valid range has side effects. Such things make error finding sometimes the hell, and hence should be avoided. IMHO it would be better if a language doesn't show such a behaviour but break with an error. Furthurmore, using a variable for operations of different types (as strongly seen is the case since x is used as integral number as well as boolean value) could also be error prone, even if actually used often.
Quote:Original post by haegarr
"... or else a test." It was obviously a test. So I don't understand your displeasure.



Thanks for the answer. That cleared up some confusion I had about the code.

I have no interest in guaging the capabilities of people on this forum and have never posted test question. Its neither in my interest to do so either. In real life I probably don't even know who you would be. I have been as civil as I can but if you really want me nitpick your statements and explain my displeasure I am willing to do so.

To Nitage : You say its compiler dependant but it seems to work the same way in GCC and VC++. I should probably try a couple more compilers before I assume anything though.
The more applications I write, more I find out how less I know

This topic is closed to new replies.

Advertisement