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



  • 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?



  • @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?



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



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


  • Qt Champions 2016

    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
    };
    


  • @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 :)



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



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


  • Qt Champions 2016

    @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.


  • Lifetime Qt Champion

    Hi,

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



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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.