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. Let's "switch" to Something Else

Let's "switch" to Something Else

Scheduled Pinned Locked Moved The Weird and The Wonderful
c++
34 Posts 17 Posters 0 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.
  • J jibalt

    You've missed the point ... all multibyte char literals are endian-sensitive. To make it endian-insensitive, it should be

    #define VB(a,b,c) (((((a)<<8)+(b))<<8)+(c))

    verb = VB(upper[curr->recv[0]], upper[curr->recv[1]], upper[curr->recv[2]]);

    switch (verb)
    {
    case VB('C','M','D'):
    ...

    J Offline
    J Offline
    jschell
    wrote on last edited by
    #24

    jibalt wrote:

    You've missed the point ... all multibyte char literals are endian-sensitive.
     
    To make it endian-insensitive, it should be

    That however ignores the point that the code was written to support a specific protocol over TCP. If the character set of the protocol changed then that would be just one thing that would likely break.

    J 1 Reply Last reply
    0
    • T Tom Delany

      C++ code. This is either brilliant, or just bloody awful. I'm coming down on the side of "bloody awful": recv in the curr structure below is declared as:

      BYTE recv\[64\];
      
      DWORD   verb;
      ...
      verb = (upper\[curr->recv\[0\]\] << 24) + (upper\[curr->recv\[1\]\] << 16) + (upper\[curr->recv\[2\]\] << 8) + 0x20;
      
      switch (verb)
      {
      case 'CMD ':
         ...
         break;
      
      case 'MON ':
         ...
         break;
      
      case 'END ':
         ...
         break;
      
      case 'EXT ':
         ...
         break;
      
      default:
          ...
          break;
      }
      

      WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated. There are 10 kinds of people in the world: People who know binary and people who don't.

      J Offline
      J Offline
      jschell
      wrote on last edited by
      #25

      Tom Delany wrote:

      This is either brilliant, or just bloody awful. What is the fourth character of the protocol?

      Tom Delany wrote:

      I'm coming down on the side of "bloody awful":

      How would you refactor it?

      1 Reply Last reply
      0
      • J jibalt

        I have no idea which of the things I wrote are the subject of your "oh really", but all of them are correct. As for the rest, it's a non sequitur. Both *recv and multi-char literals are endian-sensitive, so you appear to have committed a fallacy of affirmation of the consequent ... a rather basic failure of logic. But if you want to go around switching on 4-char literals thinking that it's portable, be my guest ... just don't do it in any code that might affect my life.

        B Offline
        B Offline
        BobJanova
        wrote on last edited by
        #26

        You can use big words all you like, but either 'CMD ' is endian sensitive, i.e. it is the byte stream 'C', 'M', 'D', ' ' on one system and ' ', 'D', 'M', 'C' on another, or it isn't, i.e. it's always 'C', 'M', 'D', ' ' and therefore maps to a different integer. In the first case, *recv won't be correct because the byte stream you're checking for is always the same, but the code in the original example would be, because it manually makes the integer in the big-endian manner, and that will be the value that the constant has if it switches the byte order. And if not, *recv will be correct, even if the integer interpretation of that value will be different. There is one good argument you could have deployed, which is that the standard doesn't actually define whether a multi character constant refers to byte order or integer value. But if it has a consistent meaning in real world compilers, that doesn't really matter.

        J 1 Reply Last reply
        0
        • T Tom Delany

          C++ code. This is either brilliant, or just bloody awful. I'm coming down on the side of "bloody awful": recv in the curr structure below is declared as:

          BYTE recv\[64\];
          
          DWORD   verb;
          ...
          verb = (upper\[curr->recv\[0\]\] << 24) + (upper\[curr->recv\[1\]\] << 16) + (upper\[curr->recv\[2\]\] << 8) + 0x20;
          
          switch (verb)
          {
          case 'CMD ':
             ...
             break;
          
          case 'MON ':
             ...
             break;
          
          case 'END ':
             ...
             break;
          
          case 'EXT ':
             ...
             break;
          
          default:
              ...
              break;
          }
          

          WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated. There are 10 kinds of people in the world: People who know binary and people who don't.

          M Offline
          M Offline
          Martin0815
          wrote on last edited by
          #27

          In my eyes it is ugly, but one of the easies way to compare strings (up to 8 bytes) in a most efficient way. If it's needed and documented ... ok. I recently saw a very strange way to copy an object in C++:

          1. the class defines all its data member attributes within 64 Byte

          2. the data member attributes are ordered to use alignment efficently

          3. copying the class is done this way (or similar)

            C64bitClass src, dst;

            // cast the pointer to the source/destination object to __int64 pointers
            __int64 *pnSrc = static_cast<__int64*>(&src);
            __int64 *pnDst = static_cast<__int64*>(&dst);

            // copy the first 64bit of the object - the data of the object
            *pnDst = *pnSrc;

          This really ugly, isn't it!

          1 Reply Last reply
          0
          • B BobJanova

            You can use big words all you like, but either 'CMD ' is endian sensitive, i.e. it is the byte stream 'C', 'M', 'D', ' ' on one system and ' ', 'D', 'M', 'C' on another, or it isn't, i.e. it's always 'C', 'M', 'D', ' ' and therefore maps to a different integer. In the first case, *recv won't be correct because the byte stream you're checking for is always the same, but the code in the original example would be, because it manually makes the integer in the big-endian manner, and that will be the value that the constant has if it switches the byte order. And if not, *recv will be correct, even if the integer interpretation of that value will be different. There is one good argument you could have deployed, which is that the standard doesn't actually define whether a multi character constant refers to byte order or integer value. But if it has a consistent meaning in real world compilers, that doesn't really matter.

            J Offline
            J Offline
            jibalt
            wrote on last edited by
            #28

            "You can use big words all you like" Try "git". That's a little word.

            1 Reply Last reply
            0
            • J jschell

              jibalt wrote:

              You've missed the point ... all multibyte char literals are endian-sensitive.
               
              To make it endian-insensitive, it should be

              That however ignores the point that the code was written to support a specific protocol over TCP. If the character set of the protocol changed then that would be just one thing that would likely break.

              J Offline
              J Offline
              jibalt
              wrote on last edited by
              #29

              No, I did not ignore your irrelevant point.

              J 1 Reply Last reply
              0
              • J jibalt

                No, I did not ignore your irrelevant point.

                J Offline
                J Offline
                jschell
                wrote on last edited by
                #30

                jibalt wrote:

                No, I did not ignore your irrelevant point.

                Your comments are only relevent if the character set changes - and thus the protocol changed. Thus your comment, in terms of the original question, is irrelevant. And I seriously doubt it would ever be relevant because it presumes that the protocol is compiler dependent. Even if the protocol did specially use a multi-byte character set which varied by OS then then the correct thing for the protocol to do is send a precursor to determine the ordering. Your code presumes and ordering and ignores the possibility that the other end is running on a different OS.

                J 1 Reply Last reply
                0
                • P PIEBALDconsult

                  I did similar in C about twenty years ago, but I could only fit two characters into a character literal. If you'll pardon my rusty C:

                  char* s ;
                  // read a line from a file into s
                  short* i = s ;
                  switch ( *i ) ...

                  This enabled me to easily parse some reports. I wish I still had the code. :sigh:

                  H Offline
                  H Offline
                  H Brydon
                  wrote on last edited by
                  #31

                  PIEBALDconsult wrote:

                  I did similar in C about twenty years ago, but I could only fit two characters into a character literal.
                  If you'll pardon my rusty C:

                  char* s ;
                  // read a line from a file into s
                  short* i = s ;
                  switch ( *i ) ...

                  On most hardware platforms, this will cause some alignment indigestion for every second pair of chars. Assigning a short off of an even byte boundary will usually cause a lot of work for the processor, perhaps involving exceptions and retries. I like the thinking though...

                  -- Harvey

                  P 1 Reply Last reply
                  0
                  • H H Brydon

                    PIEBALDconsult wrote:

                    I did similar in C about twenty years ago, but I could only fit two characters into a character literal.
                    If you'll pardon my rusty C:

                    char* s ;
                    // read a line from a file into s
                    short* i = s ;
                    switch ( *i ) ...

                    On most hardware platforms, this will cause some alignment indigestion for every second pair of chars. Assigning a short off of an even byte boundary will usually cause a lot of work for the processor, perhaps involving exceptions and retries. I like the thinking though...

                    -- Harvey

                    P Offline
                    P Offline
                    PIEBALDconsult
                    wrote on last edited by
                    #32

                    I only did it with the first two characters per line.

                    H 1 Reply Last reply
                    0
                    • P PIEBALDconsult

                      I only did it with the first two characters per line.

                      H Offline
                      H Offline
                      H Brydon
                      wrote on last edited by
                      #33

                      For a string, that could still be at an odd address.

                      -- Harvey

                      1 Reply Last reply
                      0
                      • J jschell

                        jibalt wrote:

                        No, I did not ignore your irrelevant point.

                        Your comments are only relevent if the character set changes - and thus the protocol changed. Thus your comment, in terms of the original question, is irrelevant. And I seriously doubt it would ever be relevant because it presumes that the protocol is compiler dependent. Even if the protocol did specially use a multi-byte character set which varied by OS then then the correct thing for the protocol to do is send a precursor to determine the ordering. Your code presumes and ordering and ignores the possibility that the other end is running on a different OS.

                        J Offline
                        J Offline
                        jibalt
                        wrote on last edited by
                        #34

                        Was that meant to be English?

                        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