Search code examples
c++local-variablesstatic-variables

C++ function returning address of static array


In the following code block...

#include <iostream>

int* a() 
{
  static int nums[] = { 1, 2, 3 };
  return nums;
}

int* const& b() 
{
  static int nums[] = { 4, 5, 6 };
  return nums;
}

void c( int*& num )
{
  if ( num )
  {
    std::cout << "I got " << *num << std::endl;
  }
}

void d( int* const& num )
{
  if ( num )
  {
    std::cout << "I got " << *num << std::endl;
  }
}

int main( int argc, char* argv[] )
{
  int* nums = a();
  std::cout << nums[1] << std::endl;

  int* const nums2 = b();
  std::cout << nums2[1] << std::endl;

  int* num = new int(64);
  c( num );
  delete num;

  int num2 = 101;
  d( &num2 );
}

... why does function int* const& b() generate the following compile warning?

sh-4.2$ g++ -o main *.cpp                                                                                                                                                                                
main.cpp: In function 'int* const& b()':                                                                                                                                                                 
main.cpp:12:10: warning: returning reference to temporary [-Wreturn-local-addr]                                                                                                                          
   return nums;

I figure nums in b() is static, therefore in the data section of memory, so is not subject to the problem of returning an address of a truly function-local variable.

I tried compiling and running this code on my desktop and two online C++ compilers. Executable runs fine on the desktop and one online compiler, but on the second online compiler, it dies early after printing "2". But I don't have access to a core file, nor did I see a stack trace to see what actually went wrong. (Working online compiler was tutorialspoint and non-working online compiler was codechef)

I'm particularly puzzled why b() generates this warning and/or runtime error whereas a() does not.


Solution

  • The reason this happens is that nums is not a pointer, it is an array. Although C++ will implicitly convert it to a pointer as needed, taking a reference to the array and representing it as a pointer would require a temporary. Essentially, C++ will do this:

    static int nums[] = { 4, 5, 6 };
    int* invisible = nums;
    return invisible;
    

    Making a static pointer and taking a reference to it will fix this warning:

    static int data[] = { 4, 5, 6 };
    static int* nums = data;
    return nums;
    

    Alternatively, you could typedef a fixed-length array, and use it as the return type of b():

    typedef int array3[3];
    
    array3 const& b()
    { 
      static int nums[] = { 4, 5, 6 };
      return nums;
    }
    ...
    array3 const &nums2 = b();