我使用 gcc8 编译这段代码:
#include <iostream>
class person
{
public:
virtual void setage()=0;
};
void test(person &object)
{
if (&object == NULL) {
std::cout << "NULL object1" << std::endl;
}
if (!(&object))
{
std::cout << "NULL object1" << std::endl;
}
}
int main()
{
person *object=NULL;
person &object1=*object;
test(object1);
}
然后,编译并运行后出现两个警告:
$g++ -std=c++14 -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread -pedantic-errors main.cpp -lm -latomic -lstdc++fs && ./a.out
main.cpp: 在函数"void test(person&)"中:
主.cpp:11:17: 警告:编译器可以假定 "对象"永远不会为空 [-waddress]
if (&object == NULL) { ^
主.cpp:15:18: 警告:编译器可以假定 "对象"永远不会为空 [-waddress]
if (!(&object)) ^
主.cpp:15:5: 警告:与 NULL 相比,非空参数"对象" [-Wnonnull-compare]
if (!(&object)) ^~
主.cpp:11:5: 警告:非空参数"对象"与 NULL 相比 [-Wnonnull-compare]
if (&object == NULL) { ^~
- 为什么函数中
object
的地址test
甚至将 NULL 引用值传递给它也不是 NULL? - 似乎函数
test
中的引用object
永远不能为 NULL,因此我们可以删除代码if (&object == NULL){...}
并if (&object == NULL) {...}
以避免这两个警告,对吗?
感谢您的提示。
引用在格式良好的C++程序中永远不会为空。初始化引用的唯一有效方法是将其绑定到有效对象。可能发生"空引用"的唯一方法是取消引用空指针,就像您一样。但是,即使在您检查之前,程序的行为&object == NULL
也是未定义的。该错误存在于传递"null 引用"的代码中,必须在那里修复。
因此,编译器警告您添加了一个多余的检查,可以保护您免受很少甚至没有,因为需要修复的损坏代码在您的函数之外。
Person* ptr_object = NULL;
Person& ref_object= *ptr_object;
通过取消引用ptr_object此处,您正在取消引用 NULL 指针,这是未定义的行为。引用不应引用 NULL。