Home > Software engineering >  Trying to write low-level bit library, but I get an error, or garbage when trying to cast byte struc
Trying to write low-level bit library, but I get an error, or garbage when trying to cast byte struc

Time:07-26

I'm trying to write functions to access individual bits in a byte, word, dword, or qword with an object-oriented style in ANSI C, but I'm not getting the results I imagine I should be. The bit type is declared like this:

typedef enum {F=0,T=1} bit;

The byte type is declared as a struct:

typedef struct {
    bit b0:1;
    bit b1:1;
    bit b2:1;
    bit b3:1;
    bit b4:1;
    bit b5:1;
    bit b6:1;
    bit b7:1;
} byte;

I then use the function makebyte to create the byte. This is defined like so:

byte makebyte(bit b7, bit b6, bit b5, bit b4, bit b3, bit b2, bit b1, bit b0){
    byte out;
    out.b0=b0;
    out.b1=b1;
    out.b2=b2;
    out.b3=b3;
    out.b4=b4;
    out.b5=b5;
    out.b6=b6;
    out.b7=b7;
    return out;
}

Then I'm trying to convert this struct to a single byte char type, like this:

char byteval(byte b){
    char *out=(char)&b;
    return out;
}

Then here I call it in my main function:

int main(int argc, char **argv){
    byte k;
    k=makebyte(0,0,1,0,0,1,0,0);
    printf("%c\n\n", byteval(k));
}

Now, my problem is that I'm basically getting garbage printed to the terminal instead of the ASCII character I'm looking for, '$'

I'm trying To Make the code Clean and Readable, since I plan on releasing it in the Public Domain. Thanks in advance!

CodePudding user response:

This:

char byteval(byte b){
    char *out=(char)&b;
    return out;
}

Is invalid for two reasons, actually the same reason twice.

On the first line, you're converting an address to a char type, then converting it back to a pointer type. Converting a pointer to an integer type and back is only valid if the integer type is large enough to hold the pointer value, which in this case it's not.

You should be converting to a char *:

char *out = (char *)&b;

On the second line, you're converting a pointer to a char again and returning it from the function. You don't actually want to return the pointer, but what the pointer points to:

return *out;

CodePudding user response:

char byteval(byte b){
    char *out=(char)&b;
    return out;
}

In this function you actually convert the ADDRESS of b to a 8-bit value, and then return this casted adress, but not the value. You should write:

char byteval(byte b){
    char *out=(char *)&b;
    return *out;
}

And if you get problems of wrong value later on, you can refer to my kernel code:

typedef struct __attribute__((packed)) {
    uint64_t            : 16, // unused
                        : 24, // unused
                Type    : 4,
                S       : 1, // 0=system seg, 1=common seg
                DPL     : 2,
                P       : 1, // segment present
                        : 5, // unused
                L       : 1, // 0=dataseg, 1=codeseg
                        : 10; // unused
} segdesc64_T;

This structure takes up 64-bit and used by cpu, since my kernel works well, I think it is a valid declaration.

  • Related