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. Ambiguity for `QByteArray:fromRawData` expecting `char` array
QtWS25 Last Chance

Ambiguity for `QByteArray:fromRawData` expecting `char` array

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 2.7k Views
  • 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.
  • L Offline
    L Offline
    lotuz 0
    wrote on last edited by
    #1

    Hi,

    If I try to compile the example code for QByteArray::fromRawData:

    static const char mydata[] = {
           0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
           0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
           0x6d, 0x5b
    };
    
    QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
    

    I get the a Wnarrowing warning:

    ../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
    

    That is, because my system interprets char as signed char by default.

    Maybe it is worth putting a "Note" there mentioning that?

    As a feature request, can the constructor not also take signed char or unsigned char arrays to circumvent this ambiguity?

    JonBJ kshegunovK 2 Replies Last reply
    0
    • L lotuz 0

      Hi,

      If I try to compile the example code for QByteArray::fromRawData:

      static const char mydata[] = {
             0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
             0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
             0x6d, 0x5b
      };
      
      QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
      

      I get the a Wnarrowing warning:

      ../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
      

      That is, because my system interprets char as signed char by default.

      Maybe it is worth putting a "Note" there mentioning that?

      As a feature request, can the constructor not also take signed char or unsigned char arrays to circumvent this ambiguity?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @lotuz-0

      static const unsigned char mydata[] = { ... }
      
      QByteArray::fromRawData(reinterpret_cast<const char*>(mydata), sizeof(mydata))
      

      Would that fix it?

      Or, does your compiler have a #pragma to switch off Wnarrowing which you could surround the initialization with?

      L 1 Reply Last reply
      1
      • JonBJ JonB

        @lotuz-0

        static const unsigned char mydata[] = { ... }
        
        QByteArray::fromRawData(reinterpret_cast<const char*>(mydata), sizeof(mydata))
        

        Would that fix it?

        Or, does your compiler have a #pragma to switch off Wnarrowing which you could surround the initialization with?

        L Offline
        L Offline
        lotuz 0
        wrote on last edited by lotuz 0
        #3

        @JNBarchan that works like a charm, yes. I have no idea why my thoughts were way to complicated :) Thank you!

        Still, as char can be either unsigned or signed (depending on the platform), I still don't get why the constructor cannot take uchar arrays as an argument. Casting feels a bit unnatural within the Qt framework.

        JonBJ 1 Reply Last reply
        0
        • L lotuz 0

          @JNBarchan that works like a charm, yes. I have no idea why my thoughts were way to complicated :) Thank you!

          Still, as char can be either unsigned or signed (depending on the platform), I still don't get why the constructor cannot take uchar arrays as an argument. Casting feels a bit unnatural within the Qt framework.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @lotuz-0
          Yes, I was unsure whether you were asking for a solution or just commenting that you thought QByteArray::fromRawData() should offer an const unsigned char * parameter overload.

          As for the reason for that lacking:

          Firstly, note that the example in http://doc.qt.io/qt-5/qbytearray.html#fromRawData already has top-bit-set chars, and (presumably) the compiler they used did not have your "narrowing" warning/"my system interprets char as signed char by default". What compiler is it btw, as I've never seen this kind of warning on this kind of data, so maybe it's "unusual"?

          Secondly, there are probably loads of functions which can accept either char or unsigned char and they don't feel like writing alternate overloads for every single one (plus e.g. if they did fromRawData() here, what about the return types of data() and constData() and ....) This char being signed versus unsigned is really an issue all over the place, not just for this particular function/constructor. Presumably the narrowing/warning would not occur if all arguments were declared unsigned char rather than char as I think(?) that converts char->unsigned char without issue, but that's how it is in practice....

          L 1 Reply Last reply
          0
          • L lotuz 0

            Hi,

            If I try to compile the example code for QByteArray::fromRawData:

            static const char mydata[] = {
                   0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
                   0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
                   0x6d, 0x5b
            };
            
            QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
            

            I get the a Wnarrowing warning:

            ../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
            

            That is, because my system interprets char as signed char by default.

            Maybe it is worth putting a "Note" there mentioning that?

            As a feature request, can the constructor not also take signed char or unsigned char arrays to circumvent this ambiguity?

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

            The error you get is for the way you initialize the mydata variable, not for the way you use it after that. By default integer literals are of int type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:

            static const char mydata[] = {
                   '\x00', '\x00', '\x03', // .. and so on
            };
            

            Read and abide by the Qt Code of Conduct

            L JonBJ 2 Replies Last reply
            3
            • JonBJ JonB

              @lotuz-0
              Yes, I was unsure whether you were asking for a solution or just commenting that you thought QByteArray::fromRawData() should offer an const unsigned char * parameter overload.

              As for the reason for that lacking:

              Firstly, note that the example in http://doc.qt.io/qt-5/qbytearray.html#fromRawData already has top-bit-set chars, and (presumably) the compiler they used did not have your "narrowing" warning/"my system interprets char as signed char by default". What compiler is it btw, as I've never seen this kind of warning on this kind of data, so maybe it's "unusual"?

              Secondly, there are probably loads of functions which can accept either char or unsigned char and they don't feel like writing alternate overloads for every single one (plus e.g. if they did fromRawData() here, what about the return types of data() and constData() and ....) This char being signed versus unsigned is really an issue all over the place, not just for this particular function/constructor. Presumably the narrowing/warning would not occur if all arguments were declared unsigned char rather than char as I think(?) that converts char->unsigned char without issue, but that's how it is in practice....

              L Offline
              L Offline
              lotuz 0
              wrote on last edited by lotuz 0
              #6

              @JNBarchan I was asking for a solution to cast it nicely (I really was blind here) and was wondering about it.

              I am on 4.13.11-1-ARCH with a gcc 7.2.0 and

              #include <limits>
              std::numeric_limits<char>::is_signed;
              

              .. says it it signed. I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char). Btw the issue also only appears with arrays, e.g. char f = 0xFF does some implicit cast or something.

              Thanks for all the input! will mark it solved now :)

              L 1 Reply Last reply
              0
              • kshegunovK kshegunov

                The error you get is for the way you initialize the mydata variable, not for the way you use it after that. By default integer literals are of int type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:

                static const char mydata[] = {
                       '\x00', '\x00', '\x03', // .. and so on
                };
                
                L Offline
                L Offline
                lotuz 0
                wrote on last edited by
                #7

                @kshegunov that explains a lot! Thank you so much!

                I would say the documentation needs a change and should use character literals for initialization too.

                kshegunovK 1 Reply Last reply
                0
                • kshegunovK kshegunov

                  The error you get is for the way you initialize the mydata variable, not for the way you use it after that. By default integer literals are of int type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:

                  static const char mydata[] = {
                         '\x00', '\x00', '\x03', // .. and so on
                  };
                  
                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @kshegunov
                  You will note that the example at http://doc.qt.io/qt-5/qbytearray.html#fromRawData does the initialization just the same way as the OP, and has top-bits-set, and presumably is not expecting compiler warnings.

                  While your suggestion is correct, I suspect the OP does not want the ugliness/hassle of changing over all his initializer elements, which is why I didn't suggest it.

                  1 Reply Last reply
                  1
                  • L lotuz 0

                    @kshegunov that explains a lot! Thank you so much!

                    I would say the documentation needs a change and should use character literals for initialization too.

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

                    @lotuz-0 said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:

                    I would say the documentation needs a change and should use character literals for initialization too.

                    Yes, probably it does.

                    @JNBarchan said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:

                    You will note that the example at http://doc.qt.io/qt-5/qbytearray.html#fromRawData does the initialization just the same way as the OP

                    Noted.

                    and presumably is not expecting compiler warnings.

                    This would depend on the warning reporting level.

                    While your suggestion is correct, I suspect the OP does not want the ugliness/hassle of changing over all his initializer elements, which is why I didn't suggest it.

                    Well, it's the "correct" way of avoiding the narrowing warning. Personally, I don't like it either, but it's how C++ works.
                    Note that:

                    static const char mydata[] = {
                           0x100
                    };
                    

                    is also correct and will emit the same warning, and incidentally in this case truncation is going to happen.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    2
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Hi,

                      There's an update to the documentation on its way.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • L lotuz 0

                        @JNBarchan I was asking for a solution to cast it nicely (I really was blind here) and was wondering about it.

                        I am on 4.13.11-1-ARCH with a gcc 7.2.0 and

                        #include <limits>
                        std::numeric_limits<char>::is_signed;
                        

                        .. says it it signed. I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char). Btw the issue also only appears with arrays, e.g. char f = 0xFF does some implicit cast or something.

                        Thanks for all the input! will mark it solved now :)

                        L Offline
                        L Offline
                        lotuz 0
                        wrote on last edited by
                        #11

                        @lotuz-0 said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:

                        I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char).

                        Just to confirm: if I set the compiler flag -funsigned-char , char gets interpreted as unsigned by default and the example compiles nicely.

                        1 Reply Last reply
                        0

                        • Login

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