[英]"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 编译。
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 仍然给出警告。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
的声明中省略constexpr
和static
,这样您就可以获得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:这将在下面更详细地解释:
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
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.