Visual Studio 2019/C++ 错误?

ggo*_*ggo 2 c++ visual-studio-2012 visual-studio-2019

我在 Visual Studio 2019 16.11.8 中使用本机 C++。我不明白这一点:false关键字可以用作 NULL (或 nullptr)吗?测试代码如下:

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 *'
}
Run Code Online (Sandbox Code Playgroud)

我尝试过在线编译工具,但他们不接受

test(false);
Run Code Online (Sandbox Code Playgroud)

线,这对我来说听起来正常的行为应该是什么。

此外,此行为可能会导致重载方法出现问题。即,您有一个 test(bool* pb) 方法和一个带有指针的重载版本: 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 *'
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我也在使用 VS2012,它具有相同的行为和相同的测试代码。

use*_*522 7

MSVC 将表达式视为false指针常量

空指针常量可以隐式转换为任何指针类型,从而产生空指针值。

根据标准,正确的行为是仅将具有值的整数文字0视为空指针常量。虽然它有 value 0false但不是整数文字。

然而,该规则仅在CWG 第 903 号问题得到解决后才生效。在此之前,每个具有值的整型常量表达式0都是空指针常量。

MSVC 没有使用默认标志实现缺陷报告,并且仍然遵循这条旧规则,根据该规则,表达式false是空指针常量。

如果您给 MSVC 标志/permissive-以使其行为更加符合标准并实施新规则。如果我没记错的话,对于/std:c++20或更高版本,这也是默认设置的。

但请注意,如果您在代码中使用文字,您仍然会遇到此问题0,并且它会影响重载解析。

除 之外的值0,即使是整数文字,也永远不是空指针常量,因此不能隐式转换为指针。这也适用于true有价值的事物1。因此,重载解析可能会受到作为参数传递的特定值的影响。

空指针常量通过扩展为具有 value 的整数文字或扩展NULL为 来初始化和比较空指针。从 C++11 开始,后者是一个替代的空指针常量。NULL0nullptr