Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Appending a std::uint16_t literal constant to a QByteArray
Forum Updated to NodeBB v4.3 + New Features

Appending a std::uint16_t literal constant to a QByteArray

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 7 Posters 2.6k Views 3 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.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by
    #1

    I am trying to append the two bytes of a std::uint16_t literal constant to a QByteArray as follows:

    const std::uint16_t FOO = 0x8901;
    QByteArray ba;
    ba.append(FOO);
    

    The 0x89 byte should come first, the 0x01 byte second.

    Unerstandably, because QByteArray::append expects a char, this does not work. I get the following warning:

    warning C4305: 'argument': truncation from 'const uint16_t' to 'char'
    warning C4309: 'argument': truncation of constant value
    

    What would be the most elegant way to accomplish this? I was thinking of using one of the other overloads of QByteArray::append, but currently don't see how.

    kshegunovK VRoninV 2 Replies Last reply
    0
    • B Bart_Vandewoestyne

      I am trying to append the two bytes of a std::uint16_t literal constant to a QByteArray as follows:

      const std::uint16_t FOO = 0x8901;
      QByteArray ba;
      ba.append(FOO);
      

      The 0x89 byte should come first, the 0x01 byte second.

      Unerstandably, because QByteArray::append expects a char, this does not work. I get the following warning:

      warning C4305: 'argument': truncation from 'const uint16_t' to 'char'
      warning C4309: 'argument': truncation of constant value
      

      What would be the most elegant way to accomplish this? I was thinking of using one of the other overloads of QByteArray::append, but currently don't see how.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      @Bart_Vandewoestyne
      Same as before ;)

      QByteArray ba;
      ba.append("\x89\x01");
      

      Read and abide by the Qt Code of Conduct

      B 1 Reply Last reply
      3
      • B Bart_Vandewoestyne

        I am trying to append the two bytes of a std::uint16_t literal constant to a QByteArray as follows:

        const std::uint16_t FOO = 0x8901;
        QByteArray ba;
        ba.append(FOO);
        

        The 0x89 byte should come first, the 0x01 byte second.

        Unerstandably, because QByteArray::append expects a char, this does not work. I get the following warning:

        warning C4305: 'argument': truncation from 'const uint16_t' to 'char'
        warning C4309: 'argument': truncation of constant value
        

        What would be the most elegant way to accomplish this? I was thinking of using one of the other overloads of QByteArray::append, but currently don't see how.

        VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #3

        @Bart_Vandewoestyne said in Appending a std::uint16_t literal constant to a QByteArray:

        The 0x89 byte should come first, the 0x01 byte second

        That implies big-endian.

        const std::uint16_t FOO = 0x8901;
        QByteArray ba;
        QDataStream baStream(&ba,QIODevice::Append);
        // baStream.setByteOrder(QDataStream::BigEndian); <- already the default
        baStream << quint16(FOO);
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        5
        • kshegunovK kshegunov

          @Bart_Vandewoestyne
          Same as before ;)

          QByteArray ba;
          ba.append("\x89\x01");
          
          B Offline
          B Offline
          Bart_Vandewoestyne
          wrote on last edited by
          #4

          @kshegunov said in Appending a std::uint16_t literal constant to a QByteArray:

          QByteArray ba;
          ba.append("\x89\x01");
          

          Yes, I know that works, but I want to avoid magic constants in my code. I really would like to use the constant variable name... and the constant is defined as

          const std::uint16_t FOO = 0x8901;
          
          kshegunovK J.HilkJ 2 Replies Last reply
          0
          • B Bart_Vandewoestyne

            @kshegunov said in Appending a std::uint16_t literal constant to a QByteArray:

            QByteArray ba;
            ba.append("\x89\x01");
            

            Yes, I know that works, but I want to avoid magic constants in my code. I really would like to use the constant variable name... and the constant is defined as

            const std::uint16_t FOO = 0x8901;
            
            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @Bart_Vandewoestyne said in Appending a std::uint16_t literal constant to a QByteArray:

            and the constant is defined as

            You can't define it in a different manner? E.g.:

            static const char foo[2] = { '\x89', '\x01' };
            

            If not, then @VRonin's suggestion is probably wisest.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            1
            • Paul ColbyP Offline
              Paul ColbyP Offline
              Paul Colby
              wrote on last edited by
              #6

              Just for completeness (not necessarily recommending this) it is possible to use FOO as the std::uint16_t is already is, and without needing to use a QDataStream object, like:

              const std::uint16_t FOO = 0x8901;
              QByteArray ba;
              const auto localEndian = qFromBigEndian(FOO);
              ba.append(reinterpret_cast<const char *>(&localEndian), sizeof(FOO));
              

              Again, not saying its the best approach, but it might optimal (both memory and speed) for some scenarios? :)

              I know the reinterpret_cast can look a bit concerning, but it is perfectly valid here. However, IMO, you'd still need a some strong requirement (such as important performance optimisation) to justify this slightly less readable solution.

              Just some food for thought...

              Cheers.

              1 Reply Last reply
              3
              • B Bart_Vandewoestyne

                @kshegunov said in Appending a std::uint16_t literal constant to a QByteArray:

                QByteArray ba;
                ba.append("\x89\x01");
                

                Yes, I know that works, but I want to avoid magic constants in my code. I really would like to use the constant variable name... and the constant is defined as

                const std::uint16_t FOO = 0x8901;
                
                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by J.Hilk
                #7

                @Bart_Vandewoestyne
                to play devils advocate,
                theres always QByteArray::number

                    const std::uint16_t FOO = 0x8901;
                    
                    QByteArray ba;
                    ba.append(QByteArray::number(FOO));
                

                Never mind, just tested it does not work as I would have expected it!


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  fryn3
                  wrote on last edited by fryn3
                  #8
                  const std::uint16_t FOO = 0x8901;
                  QByteArray ba;
                  ba.append(char(FOO & 0xFF));    // 0x01
                  ba.append(char(FOO >>  8));     // 0x89
                  // or
                  ba.append(static_cast<char*>(static_cast<void*>(&FOO)), sizeof(FOO));
                  
                  aha_1980A 1 Reply Last reply
                  0
                  • F fryn3
                    const std::uint16_t FOO = 0x8901;
                    QByteArray ba;
                    ba.append(char(FOO & 0xFF));    // 0x01
                    ba.append(char(FOO >>  8));     // 0x89
                    // or
                    ba.append(static_cast<char*>(static_cast<void*>(&FOO)), sizeof(FOO));
                    
                    aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi @fryn3,

                    while your first part looks good as universal solution, the second part

                    ba.append(static_cast<char*>(static_cast<void*>(&FOO)), sizeof(FOO));

                    will only work as demanded on big endian systems, which are the minority nowadays.

                    Regards

                    Qt has to stay free or it will die.

                    F 1 Reply Last reply
                    4
                    • aha_1980A aha_1980

                      Hi @fryn3,

                      while your first part looks good as universal solution, the second part

                      ba.append(static_cast<char*>(static_cast<void*>(&FOO)), sizeof(FOO));

                      will only work as demanded on big endian systems, which are the minority nowadays.

                      Regards

                      F Offline
                      F Offline
                      fryn3
                      wrote on last edited by
                      #10

                      @aha_1980 it's work.

                      #include <iostream>
                      
                      using namespace std;
                      
                      int main()
                      {
                          uint16_t t = 0x8901;
                          cout << hex << int(t & 0xFF) << " " << int(t >> 8) << endl;
                          cout << hex << int(*(uint8_t*)&t) << " " << int(*(((uint8_t*)&t) + 1));
                      
                          return 0;
                      }
                      // output:
                      1 89
                      1 89
                      
                      1 Reply Last reply
                      0
                      • aha_1980A Offline
                        aha_1980A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @fryn3,

                        I have read the demand again, and it's like this:

                        The 0x89 byte should come first, the 0x01 byte second.

                        So the only portable way to do is your proposal, slightly adopted by me:

                        const std::uint16_t FOO = 0x8901;
                        QByteArray ba;
                        ba.append(char(FOO >>  8));     // 0x89
                        ba.append(char(FOO & 0xFF));    // 0x01
                        

                        Static casting the 16-Bit word is not endian-awere, the same applies for this one:

                        cout << hex << int((uint8_t)&t) << " " << int((((uint8_t)&t) + 1));

                        which is by the way, wrong as 0x01 comes first here.

                        And if you try this on a big endian machine, it will give other results.

                        Regards

                        Qt has to stay free or it will die.

                        1 Reply Last reply
                        3

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved