Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending booleans over the internet (Windows & Linux)

I'm sending information from my server to clients and back again using packed structs (obviously there are a lot more data in the structs)

#pragma pack(push, 1)

struct other_data_struct
{
int hp;
int wp;
char movetype;
}

struct PlayerStats
{
int playerID;
other_data_struct data;
bool friendly;    //<-this one messes up how the others are going to be packed on the 2 systems
}
#pragma pack(pop)

That works fine for all fixed sized variables, ints and chars and even other structs.

The boolean doesn't work well though when the server is compiled with gcc for Linux and the client is compiled with MSVC for windows...

I have thought of making some sort of container (ie. a unsigned char with 8 boolean get/set functions or similar) but it seems as quirky as inelegant.

Is there some way to 'pack' structs containing boolean variables exactly the same on Windows and Linux or should I bite the sour apple and use a char for each boolean?

like image 615
Valmond Avatar asked Dec 12 '25 15:12

Valmond


2 Answers

In the general case, you should not make assumptions about endianess, size of fields, structure packing etc. For general application or library development, it would be bad practice to do this kind of thing.

That said, I do this kind of thing fairly often when working on embedded systems where 1) memory (both RAM & executable ROM) is a precious resource, so unnecessary libraries need to be avoided and 2) I know my code will only target one platform, and 3) don't want to take the performance hit of packing/unpacking. Even then, it's probably not a 'best' practice.

If you are aware of the risks of doing things this way, I think you answered this one yourself. Define your own type for the boolean if you want to be 100% sure. Also beware that the size of long differs between a 32-bit and 64-bit platform. I usually stick with "stdint.h" types for every numeric primitive, that way you know what size you're dealing with.

like image 189
Brian McFarland Avatar answered Dec 14 '25 04:12

Brian McFarland


Whenever you transfer data between different systems, you should not rely on how these systems represent the data in memory, because the memory representation may vary with the processor architecture, the compiler options, and many other things. You should use some library for serialization instead, since the authors of that library have already put many thoughts into all kinds of problems that you are probably not interested in.

like image 26
Roland Illig Avatar answered Dec 14 '25 06:12

Roland Illig