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. bool to QByteArray implicit conversion curiosity?

bool to QByteArray implicit conversion curiosity?

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

    Today, while fixing standards conformance issues using VS2019's /permissive- option and Qt 5.15.1, I 'discovered' the following (when compiling without the /permissive- flag):

    The initialization

    QByteArray baTrue = true;
    

    gives the compiler error

    error C2440: 'initializing': cannot convert from 'bool' to 'QByteArray'
    message : No constructor could take the source type, or constructor overload resolution was ambiguous
    

    However, the following seems to pass:

    QByteArray baFalse = false;
    

    with the following Google Test assertions holding

        ASSERT_TRUE(baFalse.isEmpty());
        ASSERT_TRUE(baFalse.isNull());
        ASSERT_NE(baFalse, QByteArray("0"));
    

    What the hell is happening here???

    JonBJ 1 Reply Last reply
    0
    • B Bart_Vandewoestyne

      Today, while fixing standards conformance issues using VS2019's /permissive- option and Qt 5.15.1, I 'discovered' the following (when compiling without the /permissive- flag):

      The initialization

      QByteArray baTrue = true;
      

      gives the compiler error

      error C2440: 'initializing': cannot convert from 'bool' to 'QByteArray'
      message : No constructor could take the source type, or constructor overload resolution was ambiguous
      

      However, the following seems to pass:

      QByteArray baFalse = false;
      

      with the following Google Test assertions holding

          ASSERT_TRUE(baFalse.isEmpty());
          ASSERT_TRUE(baFalse.isNull());
          ASSERT_NE(baFalse, QByteArray("0"));
      

      What the hell is happening here???

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

      @Bart_Vandewoestyne
      In my gcc/clang, the statement QByteArray baFalse = false; generates the same "no viable conversion" error as QByteArray baTrue = true; does.

      I can't help what your MSVC might or might not do about this. At a guess it treats it as a match against the QByteArray::QByteArray(const char *data, int size = -1) overload:

      Constructs a byte array containing the first size bytes of array data.

      If data is 0, a null byte array is constructed.

      I am guessing that false is getting coerced to C++ 0/nullptr in your compiler?

      B 1 Reply Last reply
      3
      • JonBJ JonB

        @Bart_Vandewoestyne
        In my gcc/clang, the statement QByteArray baFalse = false; generates the same "no viable conversion" error as QByteArray baTrue = true; does.

        I can't help what your MSVC might or might not do about this. At a guess it treats it as a match against the QByteArray::QByteArray(const char *data, int size = -1) overload:

        Constructs a byte array containing the first size bytes of array data.

        If data is 0, a null byte array is constructed.

        I am guessing that false is getting coerced to C++ 0/nullptr in your compiler?

        B Offline
        B Offline
        Bart_Vandewoestyne
        wrote on last edited by
        #3

        @JonB said in bool to QByteArray implicit conversion curiosity?:

        I am guessing that false is getting coerced to C++ 0/nullptr in your compiler?

        Yep, it sure looks like that. However, at https://stackoverflow.com/questions/37214420/conversion-of-false-to-object-via-const-char-constructor I find that in C++14, also the false case should not pass (which is probably why you also got an error for false with your version of gcc/clang). However, for as far as I can see, I am using C++14 (which is the default in VS2019 apparently):

        b7200e85-f4b1-4f24-b975-bc1497c4325a-image.png

        Not completely sure why my false case then passes to be honest...

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Maybe a compiler bug/quirk. You can try it out with a simple class with this ctor

          class Foo {
            Foo(const char *);
          }
          

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          B 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            Maybe a compiler bug/quirk. You can try it out with a simple class with this ctor

            class Foo {
              Foo(const char *);
            }
            
            B Offline
            B Offline
            Bart_Vandewoestyne
            wrote on last edited by
            #5

            @Christian-Ehrlicher said in bool to QByteArray implicit conversion curiosity?:

            Maybe a compiler bug/quirk. You can try it out with a simple class with this ctor

            class Foo {
              Foo(const char *);
            }
            

            OK, so here's the program I used to test:

            struct Foo {
              Foo(const char*) {}
            };
            
            int main()
            {
                Foo f = false;
            }
            

            First, I test with the following g++ version under Cygwin:

            $ g++ --version | head -1
            g++.exe (x86_64-posix-seh, Built by strawberryperl.com project) 8.3.0
            

            C++98 compilation output only gives a warning, but compiles:

            $ g++ -std=c++98 bool_to_type_implicit_conversion.cpp
            bool_to_type_implicit_conversion.cpp: In function 'int main()':
            bool_to_type_implicit_conversion.cpp:7:13: warning: converting 'false' to pointer type for argument 1 of 'Foo::Foo(const char*)' [-Wconversion-null]
                 Foo f = false;
                         ^~~~~
            

            C++11 and C++14 compilation output gives an error:

            $ g++ -std=c++11 bool_to_type_implicit_conversion.cpp
            bool_to_type_implicit_conversion.cpp: In function 'int main()':
            bool_to_type_implicit_conversion.cpp:7:13: error: conversion from 'bool' to non-scalar type 'Foo' requested
                 Foo f = false;
                         ^~~~~
            
            $ g++ -std=c++14 bool_to_type_implicit_conversion.cpp
            bool_to_type_implicit_conversion.cpp: In function 'int main()':
            bool_to_type_implicit_conversion.cpp:7:13: error: conversion from 'bool' to non-scalar type 'Foo' requested
                 Foo f = false;
                         ^~~~~
            

            Using the Visual Studio 2019 compiler in C++14 and C++17 does not give an error:

            D:\GIT\Cpp\tests>cl /std:c++14 bool_to_type_implicit_conversion.cpp
            Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29335 for x86
            Copyright (C) Microsoft Corporation.  All rights reserved.
            
            bool_to_type_implicit_conversion.cpp
            Microsoft (R) Incremental Linker Version 14.28.29335.0
            Copyright (C) Microsoft Corporation.  All rights reserved.
            
            /out:bool_to_type_implicit_conversion.exe
            bool_to_type_implicit_conversion.obj
            
            D:\GIT\Cpp\tests>cl /std:c++17 bool_to_type_implicit_conversion.cpp
            Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29335 for x86
            Copyright (C) Microsoft Corporation.  All rights reserved.
            
            bool_to_type_implicit_conversion.cpp
            Microsoft (R) Incremental Linker Version 14.28.29335.0
            Copyright (C) Microsoft Corporation.  All rights reserved.
            
            /out:bool_to_type_implicit_conversion.exe
            bool_to_type_implicit_conversion.obj
            

            Using the Visual Studio 2019 compiler in 'c++latest' mode does give an error:

            D:\GIT\Cpp\tests>cl /std:c++latest bool_to_type_implicit_conversion.cpp
            Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29335 for x86
            Copyright (C) Microsoft Corporation.  All rights reserved.
            
            /std:c++latest is provided as a preview of language features from the latest C++
            working draft, and we're eager to hear about bugs and suggestions for improvements.
            However, note that these features are provided as-is without support, and subject
            to changes or removal as the working draft evolves. See
            https://go.microsoft.com/fwlink/?linkid=2045807 for details.
            
            bool_to_type_implicit_conversion.cpp
            bool_to_type_implicit_conversion.cpp(7): error C2440: 'initializing': cannot convert from 'bool' to 'Foo'
            bool_to_type_implicit_conversion.cpp(7): note: No constructor could take the source type, or constructor overload resolution was ambiguous
            

            I'm not sure what the correct behavior for C++11, C++14, C++17 or 'c++latest' should be, but clearly there is a difference in behavior between g++ and the cl compiler for C++14...

            1 Reply Last reply
            0
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              I would say MSVC is wrong. nullptr and false are two different values which should not be castable to each other.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              1
              • JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Bart_Vandewoestyne , @Christian-Ehrlicher
                The specifically MSVC issue seems to be https://developercommunity.visualstudio.com/content/problem/47568/false-to-pointer-implicit-conversion.html

                with Mr Microsoft seemingly only addressing this in August 2019 (my bold)

                Hi all, thank you for submitting the feedback. This wording was changed in a Defect Report against C++11, known as CWG 903. Since this is a breaking change, we've implemented it under our conformance mode /permissive-. It will be available in a future release of VS 2019--most likely VS 2019 16.4 Preview 1. You'll get another post on this thread when the fix is available.

                Then back in https://docs.microsoft.com/en-us/cpp/overview/cpp-conformance-improvements?view=msvc-160 mentioned earlier:

                Implicit conversion of integral constant expressions to null pointer

                The MSVC compiler now implements CWG Issue 903 in conformance mode (/permissive-). This rule disallows implicit conversion of integral constant expressions (except for the integer literal '0') to null pointer constants. The following example produces C2440 in conformance mode:

                int* f(bool* p) {
                    p = false; // error C2440: '=': cannot convert from 'bool' to 'bool *'
                    p = 0; // OK
                    return false; // error C2440: 'return': cannot convert from 'bool' to 'int *'
                }
                

                To fix the error, use nullptr instead of false. A literal 0 is still allowed:

                int* f(bool* p) {
                    p = nullptr; // OK
                    p = 0; // OK
                    return nullptr; // OK
                }
                
                1 Reply Last reply
                4

                • Login

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