Cast to int casting in C ++

I have a structure for representing a 29 bit CAN identifier with bit fields as follows.

struct canId
{
    u8 priority         :3; 
    u8 reserved         :1; 
    u8 dataPage         :1;     
    u8 pduFormat        :8;     
    u8 pduSpecific      :8;     
    u8 sourceAddress    :8;     
} iD;

in my code I want to copy this structure to an integer variable. Sort of:

int newId = iD; 

However, I am not sure if this is correct. Can anyone comment on this?

Edit: I can do this using the shift operator in each field, and then bitwise OR so that it is in the right place. But this makes using a structure with bit fields useless in the first place.

+4
source share
7 answers

I hope I have worked with little magic correctly ... You can do something like:

newID =  (int)iD.priority 
   | (int)(iD.reserved) << 3
   | (int)(iD.dataPage) << (3 + 1)
   | (int)(iD.pduFormat) << (3 + 1 + 1)
   | (int)(iD.pduSpecific) << (3 + 1 + 1 + 8)
   | (int)(iD.sourceAddress) << (3 + 1 + 1 + 8 + 8)

But for this you need a system that inthas at least 32 bits

+2

, , , -, 32 , memcpy int:

struct canId
{
    u8 priority         :3; 
    u8 reserved         :1; 
    u8 dataPage         :1;     
    u8 pduFormat        :8;     
    u8 pduSpecific      :8;     
    u8 sourceAddress    :8;     
    u8 _padding         :3;
} iD;

int newId = 0;
static_assert(sizeof(iD) <= sizeof(newId), "!");
memcpy(&newId, &iD, sizeof(iD));

. -punning a union .

+2

, , :

int canIdToInt(canId id) {
    int temp = 0;
    int offset = 0;

    temp |= id.sourceAddress  << offset; offset += 8;
    temp |= id.pduSpecific    << offset; offset += 8;
    temp |= id.pduFormat      << offset; offset += 8;
    temp |= id.dataPage       << offset; offset += 1;
    temp |= id.reserved       << offset; offset += 1;
    temp |= id.priority       << offset; // offset += 3; redundant

    return temp;
}

, , .

#define START_WRITE int temp=0,offset=0
#define RESULT temp

#define ADD_VALUE(X) temp |= X << offset; offset += sizeof(X)

a >

, sizeof , , , .

+2

OP , , .

-, / , user3528438.

, ( CAN), : "" struct, uint_or_whatever_t -/operator, . union struct .

! ! , ( ) struct union, , / .

, " ", , "" : , , , /. , C, bitmanip - , - , , cruft , .

.

class CanPriority {
    // the raw memory
    uint32_t m_raw;

public:
    // getter/setter methods or operators
    uint8_t get() const { /* extract, shift... */ }
    // etc.
};

class CanReserved {
    uint32_t m_raw;

public:
    uint8_t get() const { /* ... */ }
    // ...
};

union CanId {
    CanPriority priority;
    CanReserved reserved;
    // etc.
};

fwiw, - , , template , , - -O3 -flto.

+1
struct Id
{
    std::uint32_t bytes;

    // only considers least three significant bytes of x
    void priority(std::uint8_t x)
    { 
        bytes |= x & 0x03;
    }

    // only considers the least signifficant byte of x
    // sets byte into 4th bit of target value
    void reserved(std::uint8_t x)
    {
        bytes |= ((x & 0x01) << 4);
    }

    // ...
};

:

Id id;
id.priority(0x1);
id.reserved(0x0); // reset the "reserved" bit to zero

, :

u8 priority         :3; 
u8 reserved         :1; 

, , -speciffic ( ).

+1

, undefined. .

, uniont int .

, , .


union
{
    uint32_t packed;

    struct canId
    {
        u8 priority         :3; 
        u8 reserved         :1; 
        u8 dataPage         :1;     
        u8 pduFormat        :8;     
        u8 pduSpecific      :8;     
        u8 sourceAddress    :8;     
    } split;
} iD;

iD.packed= 0; iD.split.priority= 7; if (iD.packed != 0x7) ...
+1

, 29 int . , , 29 , :

( )

http://en.cppreference.com/w/cpp/language/bit_field

, fritzone .

, .

0

All Articles