Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. Tell me what's wrong with the following

Tell me what's wrong with the following

Scheduled Pinned Locked Moved The Weird and The Wonderful
20 Posts 6 Posters 150 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gary R Wheeler
    wrote on last edited by
    #1
    struct Record
    {
    	unsigned short		Length;
    	unsigned long		ObjectId;
    	LevelType			Level;
    	unsigned long	    SendBlock;
    	struct
    	{
    	    unsigned long   SendBlock       : 31;
    	    unsigned long   SendBlockMarker :  1;
    	};
    	\_\_time32\_t			SendTime;
    	struct
    	{
    		Type			SendType		: 16;
    		unsigned		SendVersion		: 16;
    	};
    	unsigned long		SendNumber;
    	union
    	{
    		struct
    		{
    			char		    Message\[1\];
    		} Version0;
    		struct
    		{
    			\_\_int64		    EventTime;
    			char		    Message\[1\];
    		} Version1;
    	};
    };
    

    :face-palm:

    Software Zen: delete this;

    Greg UtasG Mircea NeacsuM L C E 5 Replies Last reply
    0
    • G Gary R Wheeler
      struct Record
      {
      	unsigned short		Length;
      	unsigned long		ObjectId;
      	LevelType			Level;
      	unsigned long	    SendBlock;
      	struct
      	{
      	    unsigned long   SendBlock       : 31;
      	    unsigned long   SendBlockMarker :  1;
      	};
      	\_\_time32\_t			SendTime;
      	struct
      	{
      		Type			SendType		: 16;
      		unsigned		SendVersion		: 16;
      	};
      	unsigned long		SendNumber;
      	union
      	{
      		struct
      		{
      			char		    Message\[1\];
      		} Version0;
      		struct
      		{
      			\_\_int64		    EventTime;
      			char		    Message\[1\];
      		} Version1;
      	};
      };
      

      :face-palm:

      Software Zen: delete this;

      Greg UtasG Offline
      Greg UtasG Offline
      Greg Utas
      wrote on last edited by
      #2

      What's wrong isn't obvious to me. :-O It looks like SendVersion tells you which union to look at. If sent interprocessor, it will pack differently on 32-bit and 64-bit CPUs, ignoring endianism problems. The fact that there's a version number suggests that this could be the case.

      Robust Services Core | Software Techniques for Lemmings | Articles
      The fox knows many things, but the hedgehog knows one big thing.

      <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
      <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

      G 1 Reply Last reply
      0
      • Greg UtasG Greg Utas

        What's wrong isn't obvious to me. :-O It looks like SendVersion tells you which union to look at. If sent interprocessor, it will pack differently on 32-bit and 64-bit CPUs, ignoring endianism problems. The fact that there's a version number suggests that this could be the case.

        Robust Services Core | Software Techniques for Lemmings | Articles
        The fox knows many things, but the hedgehog knows one big thing.

        G Offline
        G Offline
        Gary R Wheeler
        wrote on last edited by
        #3

        There's a #pragma pack around the declaration. I'll give you a couple hints: it's before SendVersion. This compiles successfully under VS2008 (don't ask), and I've not tried compiling it under VS2019. It should trigger a compile error.

        Software Zen: delete this;

        Greg UtasG 1 Reply Last reply
        0
        • G Gary R Wheeler

          There's a #pragma pack around the declaration. I'll give you a couple hints: it's before SendVersion. This compiles successfully under VS2008 (don't ask), and I've not tried compiling it under VS2019. It should trigger a compile error.

          Software Zen: delete this;

          Greg UtasG Offline
          Greg UtasG Offline
          Greg Utas
          wrote on last edited by
          #4

          The two SendBlock fields? Maybe VS2008 accepted it because the second one was inside an unnamed struct.

          Robust Services Core | Software Techniques for Lemmings | Articles
          The fox knows many things, but the hedgehog knows one big thing.

          <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
          <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

          G 1 Reply Last reply
          0
          • G Gary R Wheeler
            struct Record
            {
            	unsigned short		Length;
            	unsigned long		ObjectId;
            	LevelType			Level;
            	unsigned long	    SendBlock;
            	struct
            	{
            	    unsigned long   SendBlock       : 31;
            	    unsigned long   SendBlockMarker :  1;
            	};
            	\_\_time32\_t			SendTime;
            	struct
            	{
            		Type			SendType		: 16;
            		unsigned		SendVersion		: 16;
            	};
            	unsigned long		SendNumber;
            	union
            	{
            		struct
            		{
            			char		    Message\[1\];
            		} Version0;
            		struct
            		{
            			\_\_int64		    EventTime;
            			char		    Message\[1\];
            		} Version1;
            	};
            };
            

            :face-palm:

            Software Zen: delete this;

            Mircea NeacsuM Offline
            Mircea NeacsuM Offline
            Mircea Neacsu
            wrote on last edited by
            #5

            In short: everything! Where should I start? The unsigned long of 1 bit? The SendBlock doubly defined? The version union with members in wrong order? The complete lack of comments? I hope they pay you well to put up with this pile of manure :wtf:

            Mircea

            Greg UtasG G 2 Replies Last reply
            0
            • Mircea NeacsuM Mircea Neacsu

              In short: everything! Where should I start? The unsigned long of 1 bit? The SendBlock doubly defined? The version union with members in wrong order? The complete lack of comments? I hope they pay you well to put up with this pile of manure :wtf:

              Mircea

              Greg UtasG Offline
              Greg UtasG Offline
              Greg Utas
              wrote on last edited by
              #6

              The union with members in the wrong order is likely correct. In Version1, EventTime was added to timestamp messages. It's followed by the Message contents, which are at the end of the message and claim to be of type char[1], but which will actually be indexed from 0 to Length - 1. Writing types for message byte buckets is fun, especially when you add protocol version control!

              Robust Services Core | Software Techniques for Lemmings | Articles
              The fox knows many things, but the hedgehog knows one big thing.

              <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
              <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

              L 1 Reply Last reply
              0
              • Greg UtasG Greg Utas

                The union with members in the wrong order is likely correct. In Version1, EventTime was added to timestamp messages. It's followed by the Message contents, which are at the end of the message and claim to be of type char[1], but which will actually be indexed from 0 to Length - 1. Writing types for message byte buckets is fun, especially when you add protocol version control!

                Robust Services Core | Software Techniques for Lemmings | Articles
                The fox knows many things, but the hedgehog knows one big thing.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Greg Utas wrote:

                type char[1], but which will actually be indexed from 0 to Length - 1

                My instincts are telling me that it's a placeholder for variable-length data. With MSVC you cannot use a zero-length array unless the following conditions are true: 1.) It must be the last field in the union or struct. 2.) Option /Za must be enabled. 3.) Option /permissive- must be unset/disabled Or you can just do char[1] :-D

                Greg UtasG G 2 Replies Last reply
                0
                • L Lost User

                  Greg Utas wrote:

                  type char[1], but which will actually be indexed from 0 to Length - 1

                  My instincts are telling me that it's a placeholder for variable-length data. With MSVC you cannot use a zero-length array unless the following conditions are true: 1.) It must be the last field in the union or struct. 2.) Option /Za must be enabled. 3.) Option /permissive- must be unset/disabled Or you can just do char[1] :-D

                  Greg UtasG Offline
                  Greg UtasG Offline
                  Greg Utas
                  wrote on last edited by
                  #8

                  And then you receive a zero-length message (header only), and someone does a memset using the size of this type, trampling over the char[1] that isn't there. :)

                  Robust Services Core | Software Techniques for Lemmings | Articles
                  The fox knows many things, but the hedgehog knows one big thing.

                  <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                  <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                  L 1 Reply Last reply
                  0
                  • Greg UtasG Greg Utas

                    And then you receive a zero-length message (header only), and someone does a memset using the size of this type, trampling over the char[1] that isn't there. :)

                    Robust Services Core | Software Techniques for Lemmings | Articles
                    The fox knows many things, but the hedgehog knows one big thing.

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    Heh, I'm not advocating the technique, I am just pointing out what I see in the struct. :)

                    1 Reply Last reply
                    0
                    • G Gary R Wheeler
                      struct Record
                      {
                      	unsigned short		Length;
                      	unsigned long		ObjectId;
                      	LevelType			Level;
                      	unsigned long	    SendBlock;
                      	struct
                      	{
                      	    unsigned long   SendBlock       : 31;
                      	    unsigned long   SendBlockMarker :  1;
                      	};
                      	\_\_time32\_t			SendTime;
                      	struct
                      	{
                      		Type			SendType		: 16;
                      		unsigned		SendVersion		: 16;
                      	};
                      	unsigned long		SendNumber;
                      	union
                      	{
                      		struct
                      		{
                      			char		    Message\[1\];
                      		} Version0;
                      		struct
                      		{
                      			\_\_int64		    EventTime;
                      			char		    Message\[1\];
                      		} Version1;
                      	};
                      };
                      

                      :face-palm:

                      Software Zen: delete this;

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Gary R. Wheeler wrote:

                      struct { Type SendType : 16; unsigned SendVersion : 16; };

                      This appears to be a bit field shared between two different data types. I am assuming Type is an enumeration type which is a signed integer. The other 16 bits are unsigned.

                      G 1 Reply Last reply
                      0
                      • Greg UtasG Greg Utas

                        The two SendBlock fields? Maybe VS2008 accepted it because the second one was inside an unnamed struct.

                        Robust Services Core | Software Techniques for Lemmings | Articles
                        The fox knows many things, but the hedgehog knows one big thing.

                        G Offline
                        G Offline
                        Gary R Wheeler
                        wrote on last edited by
                        #11

                        BINGO!

                        Software Zen: delete this;

                        1 Reply Last reply
                        0
                        • L Lost User

                          Greg Utas wrote:

                          type char[1], but which will actually be indexed from 0 to Length - 1

                          My instincts are telling me that it's a placeholder for variable-length data. With MSVC you cannot use a zero-length array unless the following conditions are true: 1.) It must be the last field in the union or struct. 2.) Option /Za must be enabled. 3.) Option /permissive- must be unset/disabled Or you can just do char[1] :-D

                          G Offline
                          G Offline
                          Gary R Wheeler
                          wrote on last edited by
                          #12

                          Randor wrote:

                          My instincts are telling me that it's a placeholder for variable-length data.

                          Exactly right. The struct is actually header for the information content which follows.

                          Software Zen: delete this;

                          1 Reply Last reply
                          0
                          • Mircea NeacsuM Mircea Neacsu

                            In short: everything! Where should I start? The unsigned long of 1 bit? The SendBlock doubly defined? The version union with members in wrong order? The complete lack of comments? I hope they pay you well to put up with this pile of manure :wtf:

                            Mircea

                            G Offline
                            G Offline
                            Gary R Wheeler
                            wrote on last edited by
                            #13

                            Mircea Neacsu wrote:

                            The unsigned long of 1 bit?

                            An unsigned value 1 bit in width is slightly more useful than a signed value 1 bit in width, if you think about it.

                            Mircea Neacsu wrote:

                            The SendBlock doubly defined?

                            That's the error I was referring to. IMO the compiler should issue an error, since the identifier SendBlock is ambiguous when referencing fields in the struct. This code is compiled using VS2008 which does not issue a diagnostic.

                            Mircea Neacsu wrote:

                            The version union with members in wrong order?

                            They're in the correct order. The Message value must be at the end of the structure, since it is a placeholder for the beginning of the variable-length data that's included in the message.

                            Mircea Neacsu wrote:

                            The complete lack of comments?

                            This is a code fragment, extracted from a header file that provides more context.

                            Mircea Neacsu wrote:

                            hope they pay you well to put up with this pile of manure :WTF:

                            They do pay me well, in the coin that really matters: appreciation. I've worked for the same company for over 30 years, and have survived numerous "workforce reduction" actions during the last period of financial instability. As to its fecal quality, I didn't create this originally but I have maintained it over the last 20 years. This 'weird & wonderful' came up during some refactoring I'm doing while adding a new feature.

                            Software Zen: delete this;

                            Mircea NeacsuM 1 Reply Last reply
                            0
                            • L Lost User

                              Gary R. Wheeler wrote:

                              struct { Type SendType : 16; unsigned SendVersion : 16; };

                              This appears to be a bit field shared between two different data types. I am assuming Type is an enumeration type which is a signed integer. The other 16 bits are unsigned.

                              G Offline
                              G Offline
                              Gary R Wheeler
                              wrote on last edited by
                              #14

                              As someone else mentioned, this is part of a message protocol definition. This struct was originally a single, unsigned 32-bit value called SendType which was indeed an enumeration. We've occasionally had the need to add features without removing the ability to handle older versions. This was one solution to the problem. Messages in the original format (which don't know about SendVersion) therefore have an appropriate SendType with a SendVersion of zero (0).

                              Software Zen: delete this;

                              C 1 Reply Last reply
                              0
                              • G Gary R Wheeler

                                Mircea Neacsu wrote:

                                The unsigned long of 1 bit?

                                An unsigned value 1 bit in width is slightly more useful than a signed value 1 bit in width, if you think about it.

                                Mircea Neacsu wrote:

                                The SendBlock doubly defined?

                                That's the error I was referring to. IMO the compiler should issue an error, since the identifier SendBlock is ambiguous when referencing fields in the struct. This code is compiled using VS2008 which does not issue a diagnostic.

                                Mircea Neacsu wrote:

                                The version union with members in wrong order?

                                They're in the correct order. The Message value must be at the end of the structure, since it is a placeholder for the beginning of the variable-length data that's included in the message.

                                Mircea Neacsu wrote:

                                The complete lack of comments?

                                This is a code fragment, extracted from a header file that provides more context.

                                Mircea Neacsu wrote:

                                hope they pay you well to put up with this pile of manure :WTF:

                                They do pay me well, in the coin that really matters: appreciation. I've worked for the same company for over 30 years, and have survived numerous "workforce reduction" actions during the last period of financial instability. As to its fecal quality, I didn't create this originally but I have maintained it over the last 20 years. This 'weird & wonderful' came up during some refactoring I'm doing while adding a new feature.

                                Software Zen: delete this;

                                Mircea NeacsuM Offline
                                Mircea NeacsuM Offline
                                Mircea Neacsu
                                wrote on last edited by
                                #15

                                Gary R. Wheeler wrote:

                                An unsigned value 1 bit in width is slightly more useful than a signed value 1 bit in width, if you think about it.

                                Yes, but long... :confused:

                                Gary R. Wheeler wrote:

                                They do pay me well, in the coin that really matters: appreciation. I've worked for the same company for over 30 years,

                                I understand. I've worked for the same company for 22 years and enjoyed every minute of it... well, at least most minutes :laugh:

                                Mircea

                                G 1 Reply Last reply
                                0
                                • Mircea NeacsuM Mircea Neacsu

                                  Gary R. Wheeler wrote:

                                  An unsigned value 1 bit in width is slightly more useful than a signed value 1 bit in width, if you think about it.

                                  Yes, but long... :confused:

                                  Gary R. Wheeler wrote:

                                  They do pay me well, in the coin that really matters: appreciation. I've worked for the same company for over 30 years,

                                  I understand. I've worked for the same company for 22 years and enjoyed every minute of it... well, at least most minutes :laugh:

                                  Mircea

                                  G Offline
                                  G Offline
                                  Gary R Wheeler
                                  wrote on last edited by
                                  #16

                                  Mircea Neacsu wrote:

                                  Yes, but long

                                  In this environment, 32 bits. The original value was an unsigned long.

                                  Software Zen: delete this;

                                  1 Reply Last reply
                                  0
                                  • G Gary R Wheeler

                                    As someone else mentioned, this is part of a message protocol definition. This struct was originally a single, unsigned 32-bit value called SendType which was indeed an enumeration. We've occasionally had the need to add features without removing the ability to handle older versions. This was one solution to the problem. Messages in the original format (which don't know about SendVersion) therefore have an appropriate SendType with a SendVersion of zero (0).

                                    Software Zen: delete this;

                                    C Offline
                                    C Offline
                                    charlieg
                                    wrote on last edited by
                                    #17

                                    This smells like nifty code. Nifty code is brittle. If it's difficult to understand a struct, you're doing it wrong. That said, you have existing code and must maintain compatibility so...

                                    Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                                    G 1 Reply Last reply
                                    0
                                    • C charlieg

                                      This smells like nifty code. Nifty code is brittle. If it's difficult to understand a struct, you're doing it wrong. That said, you have existing code and must maintain compatibility so...

                                      Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                                      G Offline
                                      G Offline
                                      Gary R Wheeler
                                      wrote on last edited by
                                      #18

                                      charlieg wrote:

                                      This smells like nifty code. Nifty code is brittle. If it's difficult to understand a struct, you're doing it wrong.

                                      I heartily agree. This struct defines the message format used by our in-house diagnostic tool. Our applications are multi-machine, multi-process, and multithreaded. Each process includes a small TCP/IP socket-based server that communicates with a client application. Code in the process uses the server like printf on steroids. The client in turn handles as many server connections as needed, displaying and recording them. The servers and this tool has been essential for both development and problem diagnosis in the field for us for the last 20 years. It's been maintained and refactored numerous times. We have systems in the field that are over 10 years old, so backward compatibility is an absolute requirement. The good news is the code around this definition abstracts away the awkwardness of this definition.

                                      Software Zen: delete this;

                                      1 Reply Last reply
                                      0
                                      • G Gary R Wheeler
                                        struct Record
                                        {
                                        	unsigned short		Length;
                                        	unsigned long		ObjectId;
                                        	LevelType			Level;
                                        	unsigned long	    SendBlock;
                                        	struct
                                        	{
                                        	    unsigned long   SendBlock       : 31;
                                        	    unsigned long   SendBlockMarker :  1;
                                        	};
                                        	\_\_time32\_t			SendTime;
                                        	struct
                                        	{
                                        		Type			SendType		: 16;
                                        		unsigned		SendVersion		: 16;
                                        	};
                                        	unsigned long		SendNumber;
                                        	union
                                        	{
                                        		struct
                                        		{
                                        			char		    Message\[1\];
                                        		} Version0;
                                        		struct
                                        		{
                                        			\_\_int64		    EventTime;
                                        			char		    Message\[1\];
                                        		} Version1;
                                        	};
                                        };
                                        

                                        :face-palm:

                                        Software Zen: delete this;

                                        C Offline
                                        C Offline
                                        charlieg
                                        wrote on last edited by
                                        #19

                                        And the structure is just evil completely through... If you have to stare at something like this - here's your sign.

                                        Charlie Gilley “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759 Has never been more appropriate.

                                        1 Reply Last reply
                                        0
                                        • G Gary R Wheeler
                                          struct Record
                                          {
                                          	unsigned short		Length;
                                          	unsigned long		ObjectId;
                                          	LevelType			Level;
                                          	unsigned long	    SendBlock;
                                          	struct
                                          	{
                                          	    unsigned long   SendBlock       : 31;
                                          	    unsigned long   SendBlockMarker :  1;
                                          	};
                                          	\_\_time32\_t			SendTime;
                                          	struct
                                          	{
                                          		Type			SendType		: 16;
                                          		unsigned		SendVersion		: 16;
                                          	};
                                          	unsigned long		SendNumber;
                                          	union
                                          	{
                                          		struct
                                          		{
                                          			char		    Message\[1\];
                                          		} Version0;
                                          		struct
                                          		{
                                          			\_\_int64		    EventTime;
                                          			char		    Message\[1\];
                                          		} Version1;
                                          	};
                                          };
                                          

                                          :face-palm:

                                          Software Zen: delete this;

                                          E Offline
                                          E Offline
                                          englebart
                                          wrote on last edited by
                                          #20

                                          Message would cause a name clash in the 2 struts. So MessageOld, MessageNew

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups