-1

I've been thinking about this for about a month now and have no resolution.

int* (*arr)[5];

int n[5] = {0, 1, 2, 3, 4};
int* arr_l2[5] = {&n[0], &n[1], &n[2], &n[3]};

arr = &arr_l2;

printf("%d \n", *((*arr)[2]));  // outputs 2, accessed using n[2]
printf("%p \n", *((*arr)+2));   // outputs address 0x7ffd793894e8, stack address holding value 2

Consider this code. Why would the second printf() not output 2 with the dereferencing schemes used? To me, it seems to make intuitive sense that it would because using pointer arithmetic:

*(arr + 2) is the equivalent of arr[2]

Additionally, what exactly is a & reference? I only realized today that reference parameters may be used as the variable itself, and are not like pointers, which must be dereferenced. A former professor of mine had said that pointers and references are the same, but this is obviously not true.

Could I please get a simple but thorough explanation on the number of dereferences, the reference operator, and this subtle mismatch?

  • 2
    "I only realized today that reference parameters may be used as the variable itself, and are not like pointers, which must be dereferenced." You're mixing up C++ with C. The use of `&` here has *nothing* to do with C++ references, it's creating a C pointer. There are *no* special reference types here (or anywhere in C) that directly refer to the variable and don't require dereferencing. – ShadowRanger Dec 14 '22 at 03:32
  • 1
    _"Why would the second not output 2?"_ The second uses the format specifier `%p` which outputs a pointer value. – paddy Dec 14 '22 at 03:34
  • Your compiler is likely smart enough to nuke some levels of indirection in your code. It knows that `arr` points to `arr_l2` and so `*arr` is really `arr_l2`. Further it knows that `arr_l2[2]` is really `&n[2]` and so when that is dereferenced it is really `n[2]`. And `n[]` is not assigned anywhere so it knows that `n[2]` is 2. Basically the entire expression ` *((*arr)[2])` can be reduced to `2` at compile time, so there is no indirection. – Kaz Dec 14 '22 at 03:35
  • @ShadowRanger you're right that I am. In C++, what exactly is a reference parameter? It seems to function like a pointer, but without the need of dereferencing, and I read on another thread that it occupies stack space, though I haven't verified this myself. –  Dec 14 '22 at 03:39
  • @paddy I used "%p" because it was outputting an incoherent number when it was "%d", and I wanted to use "%p" to see if it aligned with the stack address. –  Dec 14 '22 at 03:39
  • @Kaz My question is why the second would not also be "2" at compile-time. I'll edit the question for clarity. –  Dec 14 '22 at 03:40
  • @cspurposesonly: That is a *wholly* separate question, but conveniently, it's already answered [What are the differences between a pointer variable and a reference variable?](https://stackoverflow.com/q/57483/364696). In the future, don't ask multiple, largely unrelated questions together. – ShadowRanger Dec 14 '22 at 03:43

1 Answers1

1

Array indexing syntax, a[i] is exactly equivalent to *(a + i) (it's so equivalent that somearray[5] can legally be written as 5[somearray], since addition is commutative, so *(somearray + 5) and *(5 + somearray) do the same thing). So

printf("%d \n", *((*arr)[2]));

is equivalent to:

printf("%d \n", *(*((*arr) + 2)));

Note the three dereferencing *s. Your other statement only has two (and no implicit dereferencing via [i]), so it's only dereferencing two out of three layers of pointers, and does not reach the same value.

On "what exactly is a & reference? I only realized today that reference parameters may be used as the variable itself, and are not like pointers, which must be dereferenced." you're likely reading up on C++ references (which have the "no explicit dereference required" behavior). They don't exist in C. arr = &arr_l2; just says "Take the address of arr_12 and put it in arr", but it's still explicitly taking the address, and therefore reaching the underlying value will require one level of dereferencing (via *, -> or indexing syntax).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Thank you for the answer. No professor ever has given me that first explanation. That's exactly what I was looking for. For the second, you're right. I was asking about C++ and not C; I should've been more clear. I still would like an answer on it though. –  Dec 14 '22 at 03:43
  • @cspurposesonly: C++ references [are a well-covered topic already](https://stackoverflow.com/q/57483/364696). – ShadowRanger Dec 14 '22 at 03:44
  • @cspurposesonly You tagged your question as C language question. C++ is a very different language. If you want to ask about C++ you would need to use C++ language tag instead of C tag. – Gerhardh Dec 14 '22 at 05:33