代码之家  ›  专栏  ›  技术社区  ›  golvok

返回对const stuct(指针类型)成员的引用:表观左值到右值转换

  •  1
  • golvok  · 技术社区  · 7 年前

    给定以下代码,GCC会给出一些意外错误和警告。我试图通过引用返回结构的一个成员,它说我返回的是一个临时的!另外,当试图修复此函数时,它会抱怨值类别转换错误?无论如何,据我所知,对左值对象的成员访问应该产生一个左值,所以这段代码应该首先工作。怎么了?

    代码:( live on Coliru )

    const struct {
        int* iptr = nullptr;
    } cnst_struct;
    
    const int* const& return_temporary_warning() {
        return cnst_struct.iptr;
    }
    
    const int*& value_cat_convert_error() {
        return cnst_struct.iptr;
    }
    

    生产(GCC):

    main.cpp: In function 'const int* const& return_temporary_warning()':
    main.cpp:8:24: warning: returning reference to temporary [-Wreturn-local-addr]
         return cnst_struct.iptr;
                            ^~~~
    main.cpp: In function 'const int*& value_cat_convert_error()':
    main.cpp:16:24: error: cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'
         return cnst_struct.iptr;
    
                ~~~~~~~~~~~~^~~~
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   golvok    7 年前

    通过使结构成员成为指向const的指针,可以使所讨论的代码编译时没有错误或警告:

    const struct {
        const int* iptr = nullptr;
    } cnst_struct;
    

    或者,通过使函数返回非常量引用。

    这里的问题(虽然很微妙)是 iptr 成员与返回的引用的衰减类型不完全相同,因此尝试进行转换。有一个,就是 int* -> const int* 但是这个转换的结果是一个右值,因此所有的警告和错误。

    此外,Clang还发出了一个不同的警告,这也许更有帮助:

    main.cpp:8:12: warning: returning reference to local temporary object [-Wreturn-stack-address]
        return cnst_struct.iptr;
               ^~~~~~~~~~~~~~~~
    main.cpp:16:12: error: non-const lvalue reference to type 'const int *' cannot bind to a value of unrelated type 'int *const'
        return cnst_struct.iptr;
               ^~~~~~~~~~~~~~~~