3
struct test{
   char c_arr[1];
};

test array[1] = {{1}};

test get(int index){
 return array[index];
}

int main(){
  char* a =  get(0).c_arr;
  return 0;
}

Compiling this with g++ has no warnings but with clang++ prints the following:

warning: temporary whose address is used as value of local variable 'a' will be destroyed at the end of the full-expression

Is this incorrect? does get(0).c_arr not return a pointer to a global array?

or does get(0) return a temporary variable and the compiler thinks c_arr is just an instance of it, and not global, by mistake?

Edit

Why passing this temp variable to a function works without warnings?

void call(char* in){}

int main(){
  call(get(0).c_arr);
  return 0;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Dan
  • 2,694
  • 1
  • 6
  • 19

1 Answers1

6

get returns by-value, then get(0) does return a temporary which gets destroyed after the full expression, left a being a dangling pointer.

Note that the returned temporary test is copied from array[index], including the array data member c_arr. a is supposed to point to the 1st element of the data member array c_arr of the temporary test, after the full expression (i.e. the ; in char* a = get(0).c_arr;) the whole temporary test (and its data member c_arr) is destroyed, then a becomes dangling.

If get returns by-reference then it'll be fine.

test& get(int index){
 return array[index];
}

EDIT

The code you added is fine. The temporary is destroyed after the full expression, i.e. after ; in call(get(0).c_arr);. The pointer passed to call remains valid inside call.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • here end of the expression means end of `get(0).c_arr`? but `c_arr` here is returning a global pointer, which will remain valid? – Dan Jul 07 '21 at 02:46
  • @Dan No, `get` returns a `test` copied from `array[index]`, not the element of the global array directly. – songyuanyao Jul 07 '21 at 02:49
  • i see so `get(0).c_arr` returns a pointer to an array which doesn't exist anymore, not the global array. Why wouldn't `g++` warn of it tho? even `clang` when compiling `C` is ok with it? How can this be fixed in C if I may ask? – Dan Jul 07 '21 at 02:51
  • I also added an extra question under `edit`. – Dan Jul 07 '21 at 02:55
  • Thanks a lot for the information. Can I also bug you on why this woks in `C` without warnings, is it undefined behaviour? what would be a workaround as references don't exist? – Dan Jul 07 '21 at 03:04
  • @Dan I think it depends on compilers to issue a diagnostic or not. You're not using the dangling pointer. BTW dereference on it leads to UB. – songyuanyao Jul 07 '21 at 03:05
  • @Dan Answer revised for *edit*. And sorry I'm not familiar with C, not sure it's UB or not in C. – songyuanyao Jul 07 '21 at 03:06
  • Not a problem, I will ask a new question specific to C on this. – Dan Jul 07 '21 at 03:08