2
#include <stdio.h>

void test2(int (&some_array)[3]){
  // passing a specific sized array by reference? with 3 pointers?
}

void test3(int (*some_array)[3]){
  // is this passing an array of pointers?
}

void test1(int (some_array)[3]){
  // I guess this is the same as `void test1(some_array){}`, 3 is pointless.
}

int main(){
  //
  return 0;
}

What is difference between the above 3 syntaxes? I have added comments to each section to make my questions more specific.

Dan
  • 577
  • 1
  • 3
  • 9
  • Does this answer your question? [Function pointer as an argument](https://stackoverflow.com/questions/1789807/function-pointer-as-an-argument) – tadman Dec 02 '20 at 23:35
  • how is 3 not useless in the last one? – Dan Dec 02 '20 at 23:45
  • What is this code even trying to do? It's not something you'd ever see used. – tadman Dec 02 '20 at 23:46
  • 2
    Exploring the syntax of c and c++. – Dan Dec 02 '20 at 23:46
  • 1
    There's a lot of syntax to both languages, *especially* C++. Not all permutations of it are useful. – tadman Dec 02 '20 at 23:47
  • also don't function pointers have to end with `()`? like `void (*f)(int)`, my second example doesn't have that, so how is it still a function pointer? – Dan Dec 02 '20 at 23:49
  • On further reflection, this looks like an attempt to use function pointers, but it's not that. These are just extra brackets doing nothing. `int (x)` and `int ((((((((((x))))))))))` are both `int x`. In other words, this isn't a syntax thing, this is just cluttered up with useless junk. The reason I mentioned function pointers is because that's the only reason you'd use brackets there in the first place. – tadman Dec 02 '20 at 23:49
  • first one isn't a function pointer, its a legit syntax in C++, I still don't get how the second one is a FP. – Dan Dec 02 '20 at 23:51
  • None of them are function pointers. They're just lightly disguised as if they're going to be function pointers, but then the moustache falls off and you realize they're not. – tadman Dec 02 '20 at 23:52
  • See this: http://c-faq.com/aryptr/ptrtoarray.html – strupo Dec 02 '20 at 23:57

2 Answers2

5
void test2(int (&some_array)[3])

This is passing a reference to an array of 3 ints, eg:

void test2(int (&some_array)[3]) {
    ...
}

int arr1[3];
test2(arr1); // OK!

int arr2[4];
test2(arr2); // ERROR!
void test3(int (*some_array)[3])

This is passing a pointer to an array of 3 ints, eg:

void test3(int (*some_array)[3]) {
    ...
}

int arr1[3];
test3(&arr1); // OK!

int arr2[4];
test3(&arr2); // ERROR!
void test1(int (some_array)[3])

Now, this is where things get a bit interesting.

The parenthesis are optional in this case (they are not optional in the reference/pointer cases), so this is equal to

void test1(int some_array[10])

which in turn is just syntax sugar for

void test1(int some_array[])
(yes, the number is ignored)

which in turn is just syntax sugar for

void test1(int *some_array)

So, not only is the number ignored, but also it is just a simple pointer being passed in. And any fixed array decays to a pointer to its 1st element, which means that any array can be passed in, even though the declaration suggests only 3 elements are allowed, eg:

void test1(int (some_array)[3]) {
    ...
}

int arr1[3];
test1(arr1); // OK!

int arr2[10];
test1(arr2); // ALSO OK!

int *arr3 = new int[5];
test1(arr3); // ALSO OK!
delete[] arr3;

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • is there a benefit to use `reference to an array of 3 ints` over `pointer to an array of 3 ints`? are there differences? – Dan Dec 03 '20 at 01:12
  • @Dan Other than a pointer can be NULL and a reference cannot, there is no other practical difference between them. Prefer use of references, except where you actually need a pointer. – Remy Lebeau Dec 03 '20 at 01:24
1

In your code, test3 is the correct way of passing a pointer to an array, if that is what you want to.

void foo(int (*some_array)[3])
{
    for (size_t i = 0; i < 3; ++i) {
        printf("some_array[%zu]: %d\n", i, (*some_array)[i]);
    }
}

int main()
{
    int a[3] = { 4, 5, 6 };

    foo(&a);

    return 0;
}

Running this code returns what you'd expect:

some_array[0]: 4
some_array[1]: 5
some_array[2]: 6
strupo
  • 188
  • 1
  • 3
  • 14
  • in `int (*some_array)[3]`, can sizeof be used safely? also is `int (some_array)[3]` the same as `int some_array[3]{}`? – Dan Dec 03 '20 at 00:16
  • I just tested it, and you can use `sizeof(*some_array)`, it returns 12 (because one int is 4 on my machine). As for your second question, `int a[3]` is equivalent to `int (a)[3]`. – strupo Dec 03 '20 at 00:23