0

I have the following code:

int *&F(int *x) {
    int **p = &x;
    return *p;
}

int main() {
    int A[] = {0, 1, 2, 3, 4}, *y = A + 2, *&q = F(y);
    cout << *q << ' ' << *y << endl;
}

Now, i can see that we are returning the reference of x, but neither clang nor Clion (using clang-tidy) is generating warning for this code. Is this a problem for the static analysis that is too hard to follow a pointer and so to know that is pointing to or this is not returning a dangling reference?

pablo285
  • 2,460
  • 4
  • 14
  • 38
Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48
  • 3
    C++ does not require your compiler to advise you when you're about to shoot yourself in the foot. It's always nice, and courteous for your C++ compiler to warn you when you're about to shoot yourself in the foot, but there is no requirement to do so. If a compiler is sophisticated enough to figure out that you just aimed a BFG-9000 at your foot, and are about to pull the trigger, then you'll get a warning. But C++ is complicated enough that it doesn't take much before the C++ compiler does not realize that you have a BFG-9000 aimed at your foot, and allows you to pull the trigger. – Sam Varshavchik Mar 24 '20 at 21:48
  • fwiw, independent of warning or not, this shouldnt pass a code review. I believe it has UB but there are just too many `*` and `&` to be sure... – 463035818_is_not_an_ai Mar 24 '20 at 21:51

1 Answers1

3

You're not returning a reference to a local variable. You're returning a reference to whatever p points to (which, in this case, is a local variable but the static analysis doesn't see that).

If you change the function to

int *&F(int **x) {
    int **p = x;
    (*p) = (*p) - 1;
    return *p;
}

(changing the parameter to int ** instead of int *) then the problem (if any) isn't in this function at all but back with the caller.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thanks, but as it is, can I say that is safe as function? And so there is no danger to return a dandling reference? – Alberto Sinigaglia Mar 25 '20 at 00:23
  • EDIT: i've deleted the *p = * p-1 because was not important for the example... now x should be a pointer to an array of int, but x in my function is a parameter passed by value, and so its lifetime is the lifetime of the function, so when i return a reference to int where this reference turns out to be the x, why this should not be a dandling reference? i mean, we are returning a reference to a local variable no? – Alberto Sinigaglia Mar 25 '20 at 00:30
  • @Berto99 The code (original or modified) does have UB because it is returning a reference to the local `x` variable, but it isn't something that the compiler can easily detect (nor is it required to). – 1201ProgramAlarm Mar 25 '20 at 13:13