简体   繁体   中英

Visual Studio 2019/C++ bug?

I'm using native C++ with Visual Studio 2019 16.11.8. I don't understand this: whis can the false keyword be used as NULL (or nullptr)? Below the test code:

bool test(bool* pb)
{
    if (NULL != pb)
        return *pb;
    else
        return false;
}

void main()
{
    test(false); // compiles (not what I was expecting)
    test(true); // won't compile: error C2664: 'test' : cannot convert parameter 1 from 'bool' to 'bool *'
}

I have tried online compilers tool, and they do not accept the

test(false);

line, which sounds to me what the normal behavior should be.

In addition, this behavior can cause issues with overloaded methods. ie, you have a test(bool* pb) method and an overloaded version with a pointer: test(int* pv)

bool test(bool* pb)
{
    if (NULL != pb)
        return *pb;
    else
        return false;
}

bool test(int* pb)
{
    if (NULL != pb)
        return true;
    else
        return false;
}

void main()
{
    test(false); // won't compile anymore: error C2668: 'test' : ambiguous call to overloaded function
    test(true); // won't compile: error C2664: 'test' : cannot convert parameter 1 from 'bool' to 'bool *'
}

BTW I'm also using VS2012, which has the same behavior with the same test codes.

MSVC treats the expression false as a null pointer constant .

A null pointer constant can be implicitly converted to any pointer type, resulting in a null pointer value.

The correct behavior according to the standard is to treat only integer literals with value 0 as null pointer constants. Although it has value 0 , false is not an integer literal.

However this rule is only in place since resolution of CWG issue 903 . Before that every integral constant expression with value 0 was a null pointer constant.

MSVC is not implementing the defect report with default flags and still follows this old rule, according to which the expression false is a null pointer constant.

If you give MSVC the flag /permissive- to make it behave more standard-conform and implement the new rule. With /std:c++20 or higher this is also set by default, if I am not mistaken.

Note however, that you still have this problem if you use a literal 0 in your code and yes, it can affect overload resolution.

Values other than 0 , even if an integer literal, are never null pointer constants and therefore cannot be converted to pointers implicitly. This also applies to true which has value 1 . Therefore overload resolution may be affected by the specific value passed as argument.

Null pointer constants are what makes NULL work to initialize and compare null pointers, by having NULL expand either to an integer literal with value 0 or to nullptr . The latter is, since C++11, an alternative null pointer constant.

It is not bug. test function has like parameter pointer. false == 0 == NULL. You can have a NULL pointer. But true = 1. You cann not transform 1 (bool or int) to pointer.

Change it to:

bool test(int& pb)
{
    if (pb)
        return true;
    else
        return false;
}

An pb != NULL or pb != false is OK, but better is if(pb)

Your intention is to test a boolean value and an integer value by passing pointers to these values to test functions. However, when you call the test functions ( pb and pv ) you are inadvertently not providing pointers to these values.

test(false); // error C2668: 'test' : ambiguous call to overloaded function
test(true); // error C2664: 'test' : cannot convert parameter 1 from 'bool' to 'bool *'

In C and C++ type promotion will allow false to be treated as NULL (nullptr) because false is valued as 0. This will not be allowed for true because true is valued as 1.

The first error is due to the compiler not being able to decide which test() you want to call (because you are passing nullptr (a so called null pointer constant type ) in both cases.

The second error is due to the compiler not allowing you to convert the parameter to a pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM