14

Can anyone please explain what int ((*foo(int)))(int) in this does?

int (*fooptr)(int);
int ((*foo(int)))(int); // Can't understand what this does.

int main()
{
    fooptr = foo(0);
    fooptr(10);
}

.

hello_there_andy
  • 2,039
  • 2
  • 21
  • 51
user2839891
  • 157
  • 4
  • 1
    Since no one has mentioned it, http://c-faq.com/decl/spiral.anderson.html. Remembering some simple rules allows you to easily unravel any declaration. – chris Feb 27 '15 at 22:26
  • 2
    @chris; Not a universal rule. Fails in some cases. – haccks Feb 27 '15 at 22:28
  • @haccks: I can't think of any examples where it fails off the top of my head... Could you elaborate? – wolfPack88 Feb 27 '15 at 22:34
  • 2
    @wolfPack88; Aplly that rule on `int *a[2][3];`. – haccks Feb 27 '15 at 22:38
  • 2
    @haccks: Makes sense. Still, it's a simple modification to the rule, right? I.e., `[][]...[]` all need to be viewed as one block, and not separate. This gives you the right interpretation of `a` is an array of 2 arrays of 3 pointers to `int`. – wolfPack88 Feb 27 '15 at 22:42
  • 1
    @wolfPack88; Modification will make it worse. Read this [answer](http://stackoverflow.com/a/16265389/2455888). – haccks Feb 27 '15 at 22:44

4 Answers4

37
int ((*foo(int)))(int);

This declares foo as a function that expects an int type argument and returns a pointer to a function that expects an int type argument and return an int.

To be more clear:

          foo                           -- foo
        foo(   )                        -- is a function
        foo(int)                         --  taking an int argument
       *foo(int)                          --   returning a pointer
     (*foo(int))(  )                       --   to a function that
    (*foo(int))(int)                        --     takes an int argument
   int (*foo(int))(int)                      --     and returning an int   

Here is a good explanation for the same.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
13
foo

is what we declare.

foo(int)

It is a function that takes a single int argument

*foo(int)

and returns a pointer

((*foo(int)))(int)

to a function that takes a single int argument

int ((*foo(int)))(int)

and returns an int.

One pair of () is redundant. The same thing can be expressed as

int (*foo(int))(int)
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
8

There already answers to this, but I wanted to approach it in the opposite way.

A function declaration looks the same as a variable declaration, except that the variable name is replaced by the function name and parameters.

So this declares bar as a pointer to a function that takes an int and returns an int:

int (*bar)(int);

If, instead of a variable bar, it's a function foo(int) with that return value, you replace bar with foo(int) and get:

int (*foo(int))(int);
//    ^^^^^^^^
// this was "bar" before

Add an unnecessary pair of parentheses and you get:

int ((*foo(int)))(int);
//   ^         ^
//  extra parentheses
user253751
  • 57,427
  • 7
  • 48
  • 90
6

According to cdecl, foo is:

declare foo as function (int) returning pointer to function (int) returning int

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
imreal
  • 10,178
  • 2
  • 32
  • 48
  • 3
    I often see on SO that cdecl link is provided in answers as a solution to explain complex pointer declarations. I think that's a problem in itself, not a solution. A C , C++ programmer should understand the basic logic behind these complex declaration and then after tools like cdecl can be used. – haccks Feb 27 '15 at 22:20
  • 5
    Contrariwise, if you are going to code `int ((*foo(int)))(int)` you could either comment it or compose it of more comprehensible typedefs. If I saw this in code review, I'd probably accuse the programmer of showing off. If it doesn't go without saying, showing off in code is a Bad, Stupid Thing. – msw Feb 28 '15 at 00:15