1

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.

1 Answer 1

4

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();
Sign up to request clarification or add additional context in comments.

1 Comment

This is interesting. I always thought that because C++ did the implicit conversion that they were the same/interchangeable. Thanks for this answer: I learned something new.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.