【问题标题】:How to fix warning "the compiler can assume that the address of 'object' will never be NULL"如何修复警告“编译器可以假定‘对象’的地址永远不会为 NULL”
【发布时间】:2019-10-30 20:21:37
【问题描述】:

我使用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&)'中:

main.cpp:11:17: 警告:编译器可以假设地址 'object' 永远不会为 NULL [-Waddress]

 if (&object == NULL) {

             ^

main.cpp:15:18: 警告:编译器可以假设地址 'object' 永远不会为 NULL [-Waddress]

 if (!(&object))

              ^

main.cpp:15:5: 警告:非空参数“对象”与 NULL 相比 [-Wnonnull-compare]

 if (!(&object))

 ^~

main.cpp:11:5: 警告:非空参数“对象”与 NULL 相比 [-Wnonnull-compare]

 if (&object == NULL) {

 ^~
  1. 为什么函数test中的object的地址即使传递了NULL引用值也不是NULL?
  2. 看来函数test中的引用object永远不能为NULL,所以我们可以删除代码if (&amp;object == NULL){...}if (&amp;object == NULL) {...}来避免这两个警告,对吧?

感谢您的提示。

【问题讨论】:

  • &amp;object 永远不能是 NULL。您正在检查将始终存在的对象的地址。编译器告诉您可以删除条件。主函数中的 person &amp;object1=*object; 行尝试取消引用 NULL 指针,这将导致分段错误。
  • @MrPromethee 我用coliru编译运行,没有分段错误coliru.stacked-crooked.com/a/404da4c7eeedd154
  • 你说得对,对不起,这实际上是未定义的行为。我的观点是你不应该取消对 NULL 指针的引用。

标签: c++ gcc-warning


【解决方案1】:

在格式良好的 C++ 程序中,引用永远不会为空。初始化引用的唯一有效方法是将其绑定到有效对象。可能发生“空引用”的唯一方法是,如果您取消引用空指针,就像您所做的那样。但是,即使在您检查&amp;object == NULL 之前,您的程序的行为也是未定义的。错误在传递“空引用”的代码中,它必须在那里修复。

所以编译器警告你你添加了一个多余的检查,它可以保护你几乎没有,因为需要修复的损坏代码在你的函数之外。

【讨论】:

    【解决方案2】:
    Person* ptr_object = NULL;
    Person& ref_object= *ptr_object;
    

    通过在此处取消引用 ptr_object,您正在取消引用 NULL 指针,这是未定义的行为。引用不应引用 NULL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      相关资源
      最近更新 更多