Shift operator in C prepends ones instead of zeros

好久不见. 提交于 2019-12-25 12:49:09

问题


Here is the code:

#define u8 char
#define u32 unsigned int

typedef struct {
    //decoded instruction fields
    u8 cond; // Condition (f.ex. 1110 for always true)
    u8 instruction_code; // Is a constant since we only use branch
    u32 offset; // Offset from current PC
} dcdinst;

u8 mem[1024];

mem[0x0] = 0b11101010;

u8* instruction_addr = &mem[pc];

if (instruction_addr == NULL) {
    return false;
}

unsigned int first_part = instruction_addr[0];

// Here is the code that presents a problem:
// I try to get the upper part of the first byte
inst.cond = first_part >> 4;

first_part is the following byte: 11101010. inst.cond becomes 11111110, but I need it to be 00001110.

So, my actual problem is that I want to get the first 4 bits of my instruction which starts at the address instruction_addr. I tried to do so by using the right shift operator >> but the problem is that instead of prepending 0s to the left of the byte, it prepends 1s.

I found on stackoverflow that I first had to cast the value to a unsigned one, and that's what I did by using the variable first_part, but I still have the same problem. I don't understand why the shift seems to "see" my variable as a negative one while its type is specifically "unsigned".

Does anybody have an idea?


回答1:


Your u8 type is using char without specifying signedness, which means it has undefined signedness. It's likely your compiler is using a signed char by default. Thus, you're subject to sign-extension during operations and during promotion.

Change:

#define u8 char
#define u32 unsigned int

to:

typedef unsigned char u8;
typedef unsigned int u32;

(or use stdint.h types properly), and your storage should be actually unsigned.

Using typedefs also means the compiler is involved with this aliasing, it's not just a preprocessor text replacement, eliminating a class of subtle errors.



来源:https://stackoverflow.com/questions/43239906/shift-operator-in-c-prepends-ones-instead-of-zeros

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!