0

I have a disagreement with my colleague about sending/receiving a data structure between two machines (Also with different compilers) by UART. Our data structure has several simple variable types as its fields (like int32, uint8 and etc). In his opinion, to have a data structure with the same sequence and alignment in their fields, we have to use serializer and deserializer. Otherwise, Our code has the potential of different struct layout between two sides.

But I did it without using serializer/deserializer many times and never saw any problem. I think using from the #pragma pack(...), guarantee our purpose. Because of most differences in each compiler (In data structures compiling) occurs in fields alignment due to padding for speedup or size optimization. (Ignore the different of endianness).

For more details, We want to send/receive a struct between a Cortex-M4 (IAR) and PC (Qt in windows) by UART currently.

Am I in a wrong way? Or my friend?!

HamidReza
  • 717
  • 7
  • 17
  • 5
    It's a bad idea to rely on the structure of structs. While it might work with packing pragmas, properly serializing is far more robust. I'd say that your colleague is more correct. – Thomas Jager Aug 15 '19 at 19:53
  • 2
    Also, if you use non-fixed-width types, those can have different sizes on different platforms. – Thomas Jager Aug 15 '19 at 19:57
  • 5
    There is nothing wrong with an implementation that transmits and receives the raw bytes of a structure and documents that it requires fields of certain widths with certain representations (two’s complement and such) using bytes in a certain order with no padding. And there is nothing wrong with an implementation that serializes and deserializes its structures and sends them and documents the format it transmits and receives. Both, if properly written, conform to their specifications. Which one is suitable for a particular use depends on what purposes are to be served.… – Eric Postpischil Aug 15 '19 at 20:00
  • 2
    … Is portable code a desired goal, so the code can be run on new platforms that might use different endianness? Then you need the latter implementation. Is performance a concern and uniformity of representations across the target platforms guaranteed? Then the former implementation might be better for you. Is performance today important but you want a potential for more extensive interoperability in the future? Then maybe your code should add guards that test for endianness (likely via preprocessor conditionals some compilers provide) or include a protocol number in their transmissions. – Eric Postpischil Aug 15 '19 at 20:01
  • 2
    What is “correct” or “best” depends on the purposes to be served. It is not an absolute. – Eric Postpischil Aug 15 '19 at 20:03
  • 1
    Notice that if you've got a packed structure you need to be extra careful to never pass a pointer to an unaligned member to any function... – Antti Haapala -- Слава Україні Aug 15 '19 at 20:46
  • Related: https://stackoverflow.com/questions/30945121/dealing-with-data-serialization-without-violating-the-strict-aliasing-rule – Eugene Sh. Aug 15 '19 at 20:53
  • 1
    It's up to you: you can either write more code to make it always work, or you can write less code, but then you may have to keep tweaking it to make sure it works the same way on every compiler. – user253751 Aug 16 '19 at 02:07

1 Answers1

3

This is, I'm afraid, fundamentally a question of opinion, that can never be fully resolved.

For what it's worth, I am adamantly, vociferously with your colleague. I believe in writing explicit serializers and deserializers. I don't believe in blatting out an in-memory data structure and hoping that the other side can slurp it down without error. I don't believe in ignoring endianness differences. I believe that "blatting it out" will inevitably fail, in the end, somewhere, and I don't want to run that risk. I believe that although the explicit de/serializers may seem to be more trouble to write up front, they save time in the long run because of all the fussing and debugging you don't have to do later.

But there are also huge swaths of programmers (I suspect a significant majority) who agree entirely with you: that given enough hacking, and suitable pragmas and packing directives, you can get the "blat it out" technique to work at least most of the time, and it may be more efficient, to boot. So you're in good company, and with as many people as there are out there who obviously agree with you, I can't tell you that you're wrong.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103