Narrowing generates error



  • Hello,

    today I've downloaded new (for me) Qt 5.7 with QtCreator 4. When I compile my old program (which I have been developing with Qt 5.5 and Creator 3.6) it shows me narrowing errors (instead of previous warnings ).
    Basicly:

    const char test_data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
    

    generates

    main.cpp:64: error: narrowing conversion of '131' from 'int' to 'char' inside { } [-Wnarrowing]
         const char data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
    main.cpp:64: error: narrowing conversion of '129' from 'int' to 'char' inside { } [-Wnarrowing]
         const char data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
    main.cpp:64: error: narrowing conversion of '132' from 'int' to 'char' inside { } [-Wnarrowing]
         const char data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
    

    .pro file:

    QT       += core gui serialport printsupport
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    CONFIG += c++11
    TEMPLATE = app
    QMAKE_CXXFLAGS_WARN_ON -= Wnarrowing
    
    1. Why is that?
    2. As you see I tried disable narrowing errors (however Im not sure if I did it correctly), but it didnt fix it. How to do it than?


  • The problem here is that the numbers are outside char range (signed char is -128 to 127).
    either use unsigned char or convert the numbers to the binary equivalent in signed char e.g. 0x83 = 131 should become -125



  • As you wrote 0x83 is 03 but still it only uses 1 byte.
    I just want to disable it. I know the compiler might think I code something wrong so I just have to convince it that it is ok for me -> disable this warning.
    I need this raw data. I dont want uchar cause of convertions in other parts of code.
    Tell me, does 0x83 is held in memory in other form if I use
    char(0x83)
    or
    uchar(0x83).
    As far as I know (since the program was working correctly before) if you read it (as "raw data"), it comes the same.

    Eg everywhere where I create (not many places but tbh it was just an example)
    QByteArray ba(test_data, 5);
    I get an error about invalid construction (since it takes char*)



  • const char test_data[5] = {0x2B, -125,-127, -124, 0x0A};

    will give the same raw data with no warning

    I just tried on MSVC2013 Qt 5.5

    const char test_data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
        const char test_data2[5] = {0x2B, -125,-127, -124, 0x0A};
        bool test = std::equal(std::begin(test_data),std::end(test_data),std::begin(test_data2));
    

    and test is indeed true



  • Jesus whyyyy...
    I really rely on this hexadecimal notation.
    NOTE: diabeling c++11 fixes this one however I'd like to have c++11 features enabled as well so I would really appreciate another way to fix it


  • Qt Champions 2016

    @michelson said:

    Jesus whyyyy...

    You are overflowing an integral type, so that's why @VRonin's code is correct. (integer overflows/underflows are well defined)
    0x83 will be put into an int, but as it can't be accommodated into a char type you get the errors. In the end, you have a type mismatch - you're trying to put a square peg into a round hole and the compiler is resisting (which is pretty normal).



  • @michelson said:

    Eg everywhere where I create (not many places but tbh it was just an example)
    QByteArray ba(test_data, 5);
    I get an error about invalid construction (since it takes char*)

    you can still use unsigned char and c-cast it in the constructor

    const unsigned char test_data[5] = {0x2B, 0x83,0x81, 0x84, 0x0A};
    QByteArray ba((char*)test_data, 5);
    


  • Yep but I have to rewrite whole thing...

    QMAKE_CFLAGS_WARN_ON -= -pedantic
    QMAKE_CXXFLAGS_WARN_ON -= -pedantic
    

    partially fixes problem - partially because I get no errors but no warnings as well (which sometimes come in handy for me)


  • Qt Champions 2016

    @michelson

    Yep but I have to rewrite whole thing...

    You don't have to - you can make the cast anywhere, but you should really think about fixing the design.

    const unsigned char test_data[5] = { 0x2B, 0x83,0x81, 0x84, 0x0A };
    const char * const test_data_char = reinterpret_cast<const char * const>(test_data);
    char * test_data_dangerous = const_cast<char *>(test_data_char);
    // ... And so on
    

    partially fixes problem

    It doesn't fix the problem, it only hides it, which is much worse as it hides a lot of other potential problems.


Log in to reply
 

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