How do you declare a pointer to a function that returns a pointer to an array of int values in C / C++?

14,731

Solution 1

The right-left rule makes it easy.

int (*(*ptr)())[];can be interpreted as

Start from the variable name ------------------------------- ptr

Nothing to right but ) so go left to find * -------------- is a pointer

Jump out of parentheses and encounter () ----------- to a function that takes no arguments(in case of C unspecified number of arguments)

Go left, find * ------------------------------------------------ and returns a pointer

Jump put of parentheses, go right and hit [] ---------- to an array of

Go left again, find int ------------------------------------- ints.

Solution 2

In almost all situations where you want to return a pointer to an array the simplest thing to do is to return a pointer to the first element of the array. This pointer can be used in the same contexts as an array name an provides no more or less indirection than returning a pointer of type "pointer to array", indeed it will hold the same pointer value.

If you follow this you want a pointer to a function returning a pointer to an int. You can build this up (construction of declarations is easier than parsing).

Pointer to int:

int *A;

Function returning pointer to int:

int *fn();

pointer to function returning a pointer to int:

int *(*pfn)();

If you really want to return a pointer to a function returning a pointer to an array of int you can follow the same process.

Array of int:

int A[];

Pointer to array of int:

int (*p)[];

Function returning pointer ... :

int (*fn())[];

Pointer to fn ... :

int (*(*pfn)())[];

which is what you have.

Solution 3

You don't. Just split it up into two typedefs: one for pointer to int array, and one for pointer to functions. Something like:

typedef int (*IntArrayPtr_t)[];
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void);

This is not only more readable, it also makes it easier to declare/define the functions that you are going to assign the variable:

IntArrayPtr_t GetColumnSums(void)
{ .... }

Of course this assumes this was a real-world situation, and not an interview question or homework. I would still argue this is a better solution for those cases, but that's only me. :)

Solution 4

If you feel like cheating:

typedef int(*PtrToArray)[5];
PtrToArray function();

int i = function;

Compiling that on gcc yields: invalid conversion from 'int (*(*)())[5]' to 'int'. The first bit is the type you're looking for.

Of course, once you have your PtrToArray typedef, the whole exercise becomes rather more trivial, but sometimes this comes in handy if you already have the function name and you just need to stick it somewhere. And, for whatever reason, you can't rely on template trickery to hide the gory details from you.

If your compiler supports it, you can also do this:

typedef int(*PtrToArray)[5];
PtrToArray function();

template<typename T> void print(T) {
    cout << __PRETTY_FUNCTION__ << endl;
}

print(function);

Which, on my computer box, produces void function(T) [with T = int (* (*)())[5]]

Being able to read the types is pretty useful, since understanding compiler errors is often dependent on your ability to figure out what all those parenthesis mean. But making them yourself is less useful, IMO.

Share:
14,731
Russel
Author by

Russel

Updated on June 04, 2022

Comments

  • Russel
    Russel almost 2 years

    Is this correct?

    int (*(*ptr)())[];
    

    I know this is trivial, but I was looking at an old test about these kind of constructs, and this particular combination wasn't on the test and it's really driving me crazy; I just have to make sure. Is there a clear and solid understandable rule to these kind of declarations? (ie: pointer to... array of.. pointers to... functions that.... etc etc) Thanks!

    R

  • Mark Ransom
    Mark Ransom almost 14 years
    There's nothing easy about this. I like to use typedefs to break it down a little.
  • caf
    caf almost 14 years
    Note though that the example isn't a valid declaration - to make it one, the array size needs to be specified.
  • CB Bailey
    CB Bailey almost 14 years
    @caf: It makes the type an incomplete type but you can still use a pointer to an incomplete type in a declaration.
  • caf
    caf almost 14 years
    @Charles Bailey: So it does! I had no idea that a pointer to an incomplete array type was a useable type, but there you go. You surely do learn something new every day, as they say.