简体   繁体   English

返回对 static 成员的引用时出现“警告 C4172:返回局部变量或临时地址”

[英]"warning C4172: returning address of local variable or temporary" when returning reference to static member

I have this class with a function that returns a value.我有这个 class 和一个返回值的 function。 For complicated reasons, the value needs to be returned as a const reference.由于复杂的原因,该值需要作为const引用返回。

(minimal working example contains an int array, real code has more complex objects, hence the reference) (最小的工作示例包含一个int数组,实际代码具有更复杂的对象,因此参考)

class Foo
{
public:
    static constexpr const int OUT_OF_BOUNDS_VALUE = -9999;
    const int& ret(int i) const { return i < 0 || i > 4 ? OUT_OF_BOUNDS_VALUE : test[i]; }

private:
    int test[5] = {0, 1, 2, 3, 4};
};

This gives me warning C4172: returning address of local variable or temporary in VS2015 and it doesn't even compile with GCC.这给了我warning C4172: returning address of local variable or temporary ,它甚至不能用 GCC 编译。

  • Adding the line constexpr const int Foo::OUT_OF_BOUNDS;添加行constexpr const int Foo::OUT_OF_BOUNDS; outside of Foo lets GCC compile just fine.Foo之外让 GCC 编译得很好。 VS2015 still gives the warning. VS2015 仍然给出警告。
  • Removing constexpr and splitting the declaration from the definition fixes the warning, but why should I have to do that?删除constexpr并从定义中拆分声明可以修复警告,但为什么我必须这样做呢?

OUT_OF_BOUNDS isn't local, and it isn't temporary, right? OUT_OF_BOUNDS 不是本地的,也不是临时的,对吧? Does it not have an address when it is defined and declared inside of the class definition?在 class 定义中定义和声明它时是否没有地址?

See the warning live: https://godbolt.org/z/fv397b9rr实时查看警告: https://godbolt.org/z/fv397b9rr

What happens when you use the constexpr in your function is that a temporary local instance is created.当您在 function 中使用constexpr时会发生什么情况是创建了一个临时本地实例。 You could try to leave out constexpr and static in the declaration of your static member OUT_OF_BOUNDS so you have a const object / instance you can get a reference of.您可以尝试在您的 static 成员OUT_OF_BOUNDS的声明中省略constexprstatic ,这样您就可以获得const object / 实例的参考。

EDIT: If you must have a static member, declare it const static int and put in the definition const int Foo::OUT_OF_BOUNDS = -1;编辑:如果您必须有一个 static 成员,请将其声明为const static int并放入定义const int Foo::OUT_OF_BOUNDS = -1; in an appropriate place.在适当的地方。

test[i] is an int , you're binding it to a reference to const int in the return statement. test[i]是一个int ,您将它绑定到 return 语句中对const int的引用。 No?不?

The problem is that in C++11, we have to add a corresponding definition for a static constexpr declaration of a class' data member.问题是在 C++11 中,我们必须为类的数据成员的static constexpr 声明添加相应的定义 This is explained in more detail below:这将在下面更详细地解释:

C++11 C++11

class Foo
{
public:
    static constexpr const int OUT_OF_BOUNDS_VALUE = -9999; //THIS IS A DECLARATION IN C++11 and C++14
    //other members here
};

In the above code snippet(which is for C++11 , C++14 ), we have a declaration of the static data member OUT_OF_BOUNDS_VALUE inside the class. In the above code snippet(which is for C++11 , C++14 ), we have a declaration of the static data member OUT_OF_BOUNDS_VALUE inside the class. And so, in exactly one translation unit we have to provide a corresponding definition .因此,我们必须在一个翻译单元中提供相应的定义 Otherwise you'll get a linker error which can be seen here .否则你会得到一个linker 错误,可以在这里看到。

That is, in exactly one translation unit we should write:也就是说,我们应该在一个翻译单元中写:

constexpr const int Foo::OUT_OF_BOUNDS;//note no initializer

C++17 C++17

class Foo
{
public:
    static constexpr const int OUT_OF_BOUNDS_VALUE = -9999; //THIS IS A DEFINITION IN C++17
    //other members here
};

In the above code snippet(which is for C++17 ) we have a definition of the static data member OUT_OF_BOUNDS_VALUE inside the class.在上面的代码片段(用于C++17 )中,我们在 class 中定义了 static 数据成员OUT_OF_BOUNDS_VALUE So since C++17, we don't have to provide the definition of OUT_OF_BOUNDS_VALUE anywhere else since we already have a definition for it inside the class.因此,由于 C++17,我们不必在其他任何地方提供OUT_OF_BOUNDS_VALUE定义,因为我们已经在 class 中定义了它。


The warning that you're getting with MSVC seems to be a bug.您使用MSVC收到的警告似乎是一个错误。

暂无
暂无

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

相关问题 返回RValueRef:警告C4172:返回本地变量或临时地址 - Returning RValueRef: warning C4172: returning address of local variable or temporary 这是一个真正的问题吗:警告 C4172:返回局部变量或临时地址 - Is this a real problem: warning C4172: returning address of local variable or temporary 警告C4172返回本地变量或临时地址。 但是我返回一个输入参数值 - Warning C4172 returning address of local variable or temporary. But I return a input argument value 警告 C4172:返回对绑定到局部变量的 const std::string 的引用。 它有多安全? - Warning C4172: Returning a reference to const std::string bound to a local variable. How safe is it? C4172和C4239返回局部变量 - C4172 and C4239 returning local variable 返回指针到局部变量? (警告C4172) - Return pointer to local variable?? (warning C4172) 将本地引用返回到本地变量时,编译器为什么不警告“返回本地变量或临时地址”? - Why doesn't the compiler warn “returning address of local variable or temporary” when returning a local reference to a local variable? 为什么返回局部变量的地址或临时只是一个警告而不是错误? - Why is returning address of local variable or temporary only a warning and not an error? VS2013在返回Rvalue时警告C4172 - VS2013 warning C4172 on return Rvalue 在C ++中返回对静态局部变量的引用 - Returning reference to static local variable in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM