繁体   English   中英

Visual Studio 2019/C++ 错误?

[英]Visual Studio 2019/C++ bug?

我在 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 *'
}

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

test(false);

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

此外,此行为可能会导致重载方法出现问题。 即,您有一个 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 *'
}

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

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

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

根据标准,正确的行为是仅将值为0的 integer 文字视为 null 指针常量。 尽管它的值为0 ,但false不是 integer 文字。

但是,该规则仅在CWG 第 903号问题得到解决后才生效。 在此之前,每个值为0的整数常量表达式都是 null 指针常量。

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

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

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

0以外的值,即使是 integer 文字,也永远不是 null 指针常量,因此不能隐式转换为指针。 这也适用于值为1true 因此,重载决议可能会受到作为参数传递的特定值的影响。

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 . 后者是,自 C++11 起,另一种 null 指针常量。

这不是错误。 测试 function 有类似的参数指针。 错误 == 0 == NULL。 你可以有一个 NULL 指针。 但 true = 1。您不能将 1(bool 或 int)转换为指针。

将其更改为:

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

一个pb != NULLpb != false是可以的,但更好的是if(pb)

您的意图是通过将指向这些值的指针传递给测试函数来测试 boolean 值和 integer 值。 但是,当您调用测试函数( pbpv )时,您无意中没有提供指向这些值的指针。

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

在 C 和 C++ 类型提升中,将允许将false视为 NULL (nullptr),因为false的值为 0。因为true值不允许此为 0。

第一个错误是由于编译器无法决定您要调用哪个test() (因为您在这两种情况下都传递了 nullptr (所谓的null 指针常量类型)。

第二个错误是由于编译器不允许您将参数转换为指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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