Search code examples
c++pointersanonymouslvalue

Possible to pass address of anonymous variable?


I use anonymous variables all the time, when I have no need of a named object hanging around for the entire present scope.

I need to work with a function - outside my control - that takes a pointer as an argument and does not NULL-check. I was hoping to be able to pass the address of an anonymous variable (because I don't care about the value written at the dereferenced address), but get hit with a compile error. The simplified example below...

#include <iostream>

void ptrFunc( const int* p )
{
  if ( p )
  {
    std::cout << "*p == " << *p << std::endl;
  }
}

void refFunc( const int& i )
{
  std::cout << "(ref)i == " << i << std::endl;
}

void valueFunc( int i )
{
  std::cout << "i == " << i << std::endl;
}

int main( int argc, char* argv[] )
{
  valueFunc( int() );   // This is fine.
  refFunc( int() );     // This is also fine.
  ptrFunc( &(int()) );  // This doesn't compile.
}

...generates this compile error:

>g++ -g main.cpp 
main.cpp: In function 'int main(int, char**)':
main.cpp:25:19: error: lvalue required as unary '&' operand
   ptrFunc( &(int()) );  // This doesn't compile.
                   ^
>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 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.

The compiler error is pretty readable: an lvalue is required to use the address operator. But I'm wondering if the community can help me understand the rationale behind this restriction. It seems to me that my attempted use could reasonably be legal because the anonymous variable's lifetime is up to the semicolon, i.e. it is "alive" during ptrFunc()'s lifetime.

I considered whether it was considered "dangerous" to allow pointers to anonymous variables because of their shortened lifespan. But really any use if pointers - even for lvalues or heap-allocated objects is subject to the same problem: if someone is hanging onto any pointer, there's always the danger it could point to invalidated memory. Use of pointers is inherently dependent on careful coding, and I don't see this attempted use-case as especially different in that regard.

I'm curious to understand the rationale behind this. Thank you.

What else have I tried?

Tried compiling the example code with gcc-4.9.2 online to the same effect; so this issue is not a limitation/bug from an outdated compiler.


Solution

  • But I'm wondering if the community can help me understand the rationale behind this restriction. It seems to me that my attempted use could reasonably be legal because the anonymous variable's lifetime is up to the semicolon, i.e. it is "alive" during ptrFunc()'s lifetime.

    In this case, yes, it would work. In general, no.

    References cause the temporary's lifetime to be extended. Pointers don't. That is, given:

    int main() {
        const int & a = 1;
        int && b = 2;
        const int * c = &static_cast<const int &>(3); // don't do this
        return a + b - *c;
    }
    

    the references a and b continue to refer to valid objects. The pointer c does not, and there is no reasonable way the lifetime extension rules could work for pointers without a significant fundamental change in what pointers are. It's doable for references because references are a new (compared to C) language feature, and as a new language feature, there was no problem making them immutable. Pointers have a lot of existing code using them that would be invalidated by a change in the rules.