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 154 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.
  • 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