What does this declaration means "int(*ptr[3])();"?

Question

Whole code :

#include<stdio.h>    
 aaa(){ 
    printf("hi");  
 }  
 bbb(){  
    printf("hello");  
 }  
 ccc(){ 
    printf("ccc");  
 }  
int main(){  
     int(*ptr[3])(); 
     ptr[0]=aaa;  
     ptr[1]=bbb;  
     ptr[3]=ccc;   
     ptr[3]();   
}   

Output will be "bye".
What i can see from seeing the code that int(*ptr[3])() is some kind of declaration of array that is related to int, it is also look like function call. In lower lines of code name of functions are assigned to array, and piece of array can be used for function calling. Can somebody explain, what declaration is and how function calling is proceeding ?


Show source
| C   | c++   | syntax   | declaration   2017-01-07 11:01 7 Answers

Answers ( 7 )

  1. 2017-01-07 11:01

    It declares ptr as an array of 3 elements of type int(*)(), which is a pointer to type int(), which is a zero-arg function that returns int.

  2. 2017-01-07 11:01

    You read it boustrophedonically:

    You start from the innermost part and start reading in the direction RIGHT->LEFT.

    So here:

    int(*ptr[3])()
    

    You go to the identifier ptr that is the innermost part, then you start reading so:

    ...(*ptr[3])...
    

    ARRAY OF 3 (POINTERS TO ...)

    int(...)()
    

    ...FUNCTIONS THAT HAVE NO PROTOTYPE (C89 semantics) AND RETURN INT.

  3. 2017-01-07 11:01

    When you faced such a type, you may then use the cdecl tool to decode it :

    $ cdecl explain "int (*p[3])()"
    declare p as array 3 of pointer to function returning int
    $
    

    Beware that ptr is a reserved word for cdecl, you just have to rename the variable to something more basic...

    ------EDIT------

    Becareful that an empty list of arguments doesn't means the same in C or C++. In C that means a function with an unknown number of arguments (a C function with no args must be declared as f(void)). In C++ that means a function with no arguments.

  4. 2017-01-07 12:01

    It simply means an array of 3 pointers pointing to functions namely aaa(), bbb() and ccc(). :)

    In simpler sense, an array of 3 function pointers..

  5. 2017-01-07 12:01

    int (*ptr[3])() is a an array of 3 pointers to functions returning int.

    A bit more clearly, that means it is an array of function pointers. The array has space for 3 of them and the functions are expected to return ints.


    Some other issues with the example code

    There were a few issues with the code so I went and tidied it up.

    Assigning out of bounds in an array is undefined behaviour.

    test.c:30:3: warning: array index 3 is past the end of the array (which contains 3
    elements) [-Warray-bounds]
    ptr[3] = ccc;
    ^   ~
    test.c:23:3: note: array 'ptr' declared here
    int (*ptr[3])();
    

    Cleaned up code:

    #include <stdio.h>
    
    /* Missing function prototypes
     * For C a function taking no arguments should have void for its argument
     * For C++ void can be skipped
     */
    int aaa(void);
    int bbb(void);
    int ccc(void);
    
    /* The function should be declared with type specifier, although it is assumed
     * by default to return int.
     */
    int aaa(void) {
      /* Unless this print statement is going to be part of more output, you should
       * return a newline
       */
      printf("hi\n");
      /* As this function is meant to return an int, we will return 0*/
      return 0;
    }
    
    int bbb(void) {
      printf("hello\n");
      return 0;
    }
    
    int ccc(void) {
      printf("ccc\n");
      return 0;
    }
    
    int main(void) {
      int (*ptr[3])();
      ptr[0] = aaa;
      ptr[1] = bbb;
      /* Now assigning to valid ptr[2] and not out of bounds ptr[3] */
      ptr[2] = ccc;
      ptr[2]();
    }
    
  6. 2017-01-07 12:01

    I guess ptr[3] = ccc; is wrong here .. it's like ABW - writing out of the bound of the array. It should be ... ptr[2] = ccc;

  7. 2017-01-07 15:01

    That declaration means that someone wasn't thinking clearly. It would be much simpler if it was unrolled:

    typedef int (*fptr)();
    fptr ptr[3];
    
◀ Go back