0

Here, I have a function f() that locally defines an integer x and a pointer to it, pointer_x. And it returns that pointer. I then attempt to dereference the pointer, and it still gives me the correct integer that is pointed to by that pointer. My question is, if it is illegal for a function to locally declare an array and return that array (due to the deallocation of the stack frame as that function returns), why is it legal for a function to declare a pointer and return that pointer?

I am under the impression that an array is basically a pointer.

int *f();

int main(void){
    int *test;
    test = f();
    printf("%d", *test); //prints 0
}

int *f(){
    int x = 0; 
    int *pointer_x = &x;
    return pointer_x;
}
  • 1
    This code is broken, even if it seems working. Undefined behavior it is. – Eugene Sh. Oct 12 '18 at 20:13
  • 2
    The compiler does not validate what a pointer is actually pointing at. *In general*, returning a pointer is perfectly valid code, but returning a pointer that points at a local variable which goes out of scope when the function exits will return a *dangling pointer*, and dereferencing such a pointer is **undefined behavior**. – Remy Lebeau Oct 12 '18 at 20:13
  • `f()` is weak code (UB). C assumes the programmer is coding well and gives one all the rope they need to hang their own code. It is **not** legal for a function to declare a pointer (assigned to a local non-static object) and return that pointer – chux - Reinstate Monica Oct 12 '18 at 20:14
  • 2
    "an array is basically a pointer." is not the best view anymore than the houses in your neighborhood and the address of your house are not the same. – chux - Reinstate Monica Oct 12 '18 at 20:17
  • Or rather the sign pointing to the house... :D – Antti Haapala -- Слава Україні Oct 12 '18 at 20:18
  • 1
    I can't impress upon you how important it is to understand that "I am under the impression that an array is basically a pointer" is basically pointing in completely the wrong direction. Arrays and pointers are closely related, but an array is not a pointer and a pointer is not an array. It is crucial to understand when a pointer is a pointer and when an array is an array. C doesn't make it easy: you can write `int function(int array[SIZE]) { … }` and it looks like `array` is an array, but in the function it is a pointer rather than an array, for all you can use array subscripting to access it. – Jonathan Leffler Oct 12 '18 at 20:26
  • @JonathanLeffler does it decay at that point? Not relevant to the closed question but would sizeof not work correctly? I NEVER use function prototypes like that, always a pointer and a sizeof param. – Bwebb Oct 12 '18 at 20:32
  • In addition to that, `[]` operator can only be applied to values that are of pointer type... – Antti Haapala -- Слава Україні Oct 12 '18 at 20:34
  • 1
    @Bwebb — yes, the “decay” happens and within the function, `sizeof(array) == sizeof(`int` *)`. – Jonathan Leffler Oct 12 '18 at 20:40
  • @JonathanLeffler That is not my coding style but its still good to know when reading other peoples code. Thank you for confirming. In my previous comment I meant something like *void func(int * arry, int len)* – Bwebb Oct 12 '18 at 20:44
  • 1
    @Bwebb: I just compiled a variant of the function with GCC 8.2.0 with no extra warnings enabled, and it said: `warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘int *’ [-Wsizeof-array-argument]` — `printf("%zu\n", sizeof(array));` — `ap31.c:5:26: note: declared here` — `static void function(int array[SIZE])`. I get the same result with a VLA signature: `static void function(int size, int array[size]) { … }`. Arrays in function signatures are treated like pointers. See also C11 [§6.9.1 Function definitions ¶10](http://port70.net/~nsz/c/c11/n1570.html#6.9.1p10), etc. – Jonathan Leffler Oct 12 '18 at 21:32
  • Note that `int *f(){ int *pointer_x = malloc(...);return pointer_x;}` would not be an error. – Tim Randall Oct 12 '18 at 21:32
  • And see also C11 [§6.7.6.3 Function declarators (including prototypes) ¶7](http://port70.net/~nsz/c/c11/n1570.html#6.7.6.3p7): _A declaration of a parameter as ''array of type'' shall be adjusted to ''qualified pointer to type'', where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation._ – Jonathan Leffler Oct 12 '18 at 21:40
  • @TimRandall: The problem is more 'returning pointers to (non-static) local variables' than 'returning locally declared pointers' — but your counter-example is good. – Jonathan Leffler Oct 12 '18 at 21:42

0 Answers0