Taking address of temporary - workaround needed
Solution 1
Integer i(12);
foo(&i);
That gets rid of the "taking the address of a temporary" problem, which is what you have. You're not passing the address of a local variable (which the above does, and is indeed ok in this case), you're grabbing the address of a temporary.
Obviously, if foo
tries to hold on to that pointer one way or another, you'll have issues down the line.
Solution 2
template<typename T> const T* rvalue_address(const T& in) {
return ∈
}
In my opinion, it should be just as legal to take a const T*
as a const T&
, but this trivial function will handily perform the conversion.
Solution 3
GCC is wrong in this case. Your integer is an rvalue and taking the address of an rvalue is illegal.
§5.3.1 Unary operators, Section 3
The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.
Clang gives an error in this case:
error: taking the address of a temporary object of type 'Integer' [-Waddress-of-temporary]
foo( &Integer(12) );
^~~~~~~~~~~~
elcuco
SOreadytohelp, yea, I don't like Reggae (I love it). But not twitter.
Updated on June 15, 2022Comments
-
elcuco almost 2 years
I am facing a GCC warning that I want to fix. Basically I am passing to a method a pointer to a local variable, which in my case is perfectly OK. I understand why the compiler tells me that this is a potential problem, but in my case this is OK.
How can I workaround it, on a local space? Passing
-fpermissive
when compiling will make me fail to find future problems. I want to fix this specific problem, or workaround it.Code is available here:
#include <cstdio> class Integer{ public: Integer(int i ){ v = i; }; int value(){ return v; }; private: int v; }; int foo(Integer *i); int main() { foo( &Integer(12) ); } int foo(Integer *i) { std::printf("Integer = %d\n", i->value()); }
And compilation gives me:
$ g++ test-reference.cpp -O test-reference test-reference.cpp: In function ‘int main()’: test-reference.cpp:15:18: error: taking address of temporary [-fpermissive] $ g++ --version g++ (Ubuntu/Linaro 4.6.3-1ubuntu3) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EDIT:
Using
const
(as in makingfoo
take a const pointer, and markingvalue()
as const) gives the same error. -
Alok Save about 12 yearsyou're grabbing the address of a temporary which is very suspicious. No, it is not suspicious.The behavior is well defined,
12.2/3
Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created. -
Puppy about 12 yearsIt's no more dangerous than taking a reference to an rvalue.
-
Mat about 12 yearsOk, didn't mean to mean it was invalid, just (IMO) suspicious.
-
elcuco about 12 years@Mat, I need this to be a one liner "without" temporary variables , as this is a temporary variable generated by a DEBUG macro (in my app, its a struct that maintains information about line, file, time, threadID etc).
-
Mat about 12 years@elcuco:
{ Integer i(12); foo(&i); }
-
Mat about 12 years@elcuco: my answer already contains that. The
{}
add nothing of real value. -
ams about 12 yearsGCC is not wrong, it rejected it with
error:
because it is illegal.-fpermissive
is a GCC extension that basically says "yeah, all right, I know what you meant". Extensions are allowed to do whatever non-standard things they like because, well, they're non-standard extensions. -
Slipp D. Thompson over 9 years@Mat The value is that it makes it clear that at a high-level, this is meant as one operation and is only broken down into two for technical reasons, and it limits the scope of the single-letter
i
var, which could be considered a coding standard taboo if not used in a tightly-confined scope. -
Arne Vogel almost 9 yearsThe standard requires a diagnostic for any ill-formed program unless otherwise specified. A warning is a diagnostic. Even if GCC emitted just a warning without -fpermissive, this would not be a conformance issue.