We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, I have a Problem with the Shift-Operator >> within my C-Code. I'm using PK166 V4.2 The following code should set the Variable n to 0.
void main() { unsigned char n; unsigned char p; // dummy n=255; n=n>>22; p=0; // dummy }
MOV R5, #0x16 // incorrect Opcode??? SHR R4,R5
Is it invalid to shift a byte-variable more than 8 times? From the ANSI C standard: "If the shift count is negative or is greater than or equal to the number of bits contained in the object being shifted, the resulf of the shift is undefined" If so, why does the compiler not generate a warning? The purpose of the compiler is to compile your program, not to protect you against yourself. As you see the compilere adhere to the standard. If you want checking to this level I suggest you obtain a copy of PClint. Erik
Note that Keil EC++ catches that kind of mistake too (it throws a warning). But PC lint is even better! Steph-
"Is it invalid to shift a byte-variable more than 8 times? If so, why does the compiler not generate a warning?" Whatever, it is clearly a very silly thing to try! How did you stumble across this behaviour?
The following code should set the Variable n to 0. This expectation is based on incorrect assumptions. There's no resulting value for such an operation that would be any more, or any less wrong than any other. Is it invalid to shift a byte-variable more than 8 times? Absolutely. More to the point, it is invalid to shift any value by more than its own width, and it is risky to shift a negative value. If so, why does the compiler not generate a warning? Because it doesn't ;-> There are some specific situations in which the language definition requires a diagnostic message from the compiler --- this is not one of them. All other warnings are completely optional. A compiler is free to warn about pretty much anything it wants to --- including yesterday's weather in Neverheardofthatplace, Nevada. It's equally free to not warn about anything other than the few required issues.
Absolutely. More to the point, it is invalid to shift any value by more than its own width, and it is risky to shift a negative value. "risky"? ANSI states it undefined If so, why does the compiler not generate a warning? There are far more typical mistakes that do not generate a warning such as if (a = b) as I said in my earlier post "the compiler is not there to protect you against yourself" Erik
ANSI states it undefined You must have misread the post. It is shifting by a negative number of bits that is undefined. Shifting negative numbers is allowed, but you have to watch out for the sign bit propagation. - mike
Erik: "ANSI states it undefined" Mike: "Shifting negative numbers is allowed, but you have to watch out for the sign bit propagation." The Standard specifies that when shifting right an object having a signed type with a negative value, the resulting value is implementation-defined. The Standard defines implementation-defined as: "unspecified value where each implementation documents how the choice is made" So I interpret Mike's advice to "watch out for ..." to mean if you must do it, read the toolchain documentation to learn how your implementation handles the case.
How did you stumble across this behaviour? For debug-purpose I have written a Marcro that puts a variable (8bit, 16bit, 32bit) into a CAN-Message
debug_out(val) data[0]=(val>>24)&0xFF; data[1]=(val>>16)&0xFF; data[2]=(val>>8)&0xFF data[3]=val&0xFF; CANWRITE();
data[0]=(unsigned long) (val>>24); data[1]... ...
"I thought that a right-shift would always insert a 0 at the left side and the result would therefore be 0." Oh well - so you learned something new, anyway!
Sorry, of course I mean
data[0]= (unsigned long)val>>24;
It is, of course, possible that the standard has been updated, but my copy of the ANSI from years back state: "If the shift count is negative or is greater than or equal to the number of bits contained in the object being shifted, the result of the shift is undefined". Erik
"It is, of course, possible that the standard has been updated, but my copy of the ANSI from years back state: "If the shift count is negative or is greater than or equal to the number of bits contained in the object being shifted, the result of the shift is undefined"." Here we go again. Try reading the posts rather that replying blind. There is a difference between a 'negative shift count' and 'shifting a negative number'.
The Standard specifies that when shifting right an object having a signed type with a negative value, the resulting value is implementation-defined. It would be nice if that was CLEAR. if I shift something with a value of x that means to me that I am shifting x places. Erik
Oh, come on, Erik, you surely know better than to believe everything being said about either operand of a two-operand operator like '<<' would automatically apply to both of them. It can't be all that hard to distinguish between the number being shifted, and the number of positions it's shifted by, now can it? Negative shift counts are strictly forbidden. Shifts of negative values are implementation-defined. Which, as I said earlier, makes them risky. It would be nice if that was CLEAR. Being unmistakably clear is about the only thing a standard is required to be at all, besides not directly contradicting itself. I would say the C99 standard is quite clear indeed. It takes a while to get used to the jargon, but that's unavoidable in a text like this, which is effectively a legal and a technical document at the same time.
"The Standard specifies that when shifting right an object having a signed type with a negative value, the resulting value is implementation-defined. It would be nice if that was CLEAR." Seems perfectly clear to to me. The standard goes to great lengths to write unambiguous English. "if I shift something with a value of x that means to me that I am shifting x places." Ludicrous: 'Shift y right with x bits' 'Shift y right by x bits'.