Bulkin Bulkin - 26 days ago 13
C Question

Structs with enums are different in C and C++, why?

The task is to send data by I2C from Arduino to STM32.

So I got Struct and Enums defined in Arduino using C++:

enum PhaseCommands {
PHASE_COMMAND_TIMESYNC = 0x01,
PHASE_COMMAND_SETPOWER = 0x02,
PHASE_COMMAND_CALIBRATE = 0x03
};

enum PhaseTargets {
PHASE_CONTROLLER = 0x01,
// RESERVED = 0x02,
PHASE_LOAD1 = 0x03,
PHASE_LOAD2 = 0x04
};

struct saatProtoExec {
PhaseTargets target;
PhaseCommands commandName;
uint32_t commandBody;
} phaseCommand;

uint8_t phaseCommandBufferSize = sizeof(phaseCommand);

phaseCommand.target = PHASE_LOAD1;
phaseCommand.commandName = PHASE_COMMAND_SETPOWER;
phaseCommand.commandBody = (uint32_t)50;


On the other side I got the same defined using C:

typedef enum {
COMMAND_TIMESYNC = 0x01,
COMMAND_SETPOWER = 0x02,
COMMAND_CALIBRATE = 0x03
} MasterCommands;

typedef enum {
CONTROLLER = 0x01,
// RESERVED = 0x02,
LOAD1 = 0x03,
LOAD2 = 0x04
} Targets;

struct saatProtoExec {
Targets target;
MasterCommands commandName;
uint32_t commandBody;
} execCommand;

uint8_t execBufferSize = sizeof(execCommand);

execCommand.target = LOAD1;
execCommand.commandName = COMMAND_SETPOWER;
execCommand.commandBody = 50;


And then I compare this Structs byte-by-byte:

=====================
BYTE | C++ | C
=====================
Byte 0 -> 0x3 -> 0x3
Byte 1 -> 0x0 -> 0x2
Byte 2 -> 0x2 -> 0x0
Byte 3 -> 0x0 -> 0x0
Byte 4 -> 0x32 -> 0x32
Byte 5 -> 0x0 -> 0x0
Byte 6 -> 0x0 -> 0x0
Byte 7 -> 0x0 -> 0x0


So why bytes 1 and 2 are different?

Answer

This is a really bad idea.

You should never rely on the binary representation of structures being the same beween two implementations of C, not to mention going from C to C++!

You should do some proper serialization/deserialization code, to take control at the byte level of the structure's external representation.

That said, it could be due to padding. That you end up sending padding (which is just something added by a compiler to keep its host CPU happy) over an external link is another sign of how broken this approach is.

Comments