[英]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 指针常量,因此不能隐式转换为指针。 这也适用于值为1
的true
。 因此,重载决议可能会受到作为参数传递的特定值的影响。
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 != NULL
或pb != false
是可以的,但更好的是if(pb)
您的意图是通过将指向这些值的指针传递给测试函数来测试 boolean 值和 integer 值。 但是,当您调用测试函数( pb
和pv
)时,您无意中没有提供指向这些值的指针。
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.