Saturday, August 7, 2010

Complicated declarations in C and C++

8th, August, 2010

Complicated declarations in C and C++
I have seen few questions related to complicated declarations in C and C++. For example see the following,
  1. Declare a function with argument of int* which returns pointer to an array of integer pointers, http://geeksforgeeks.org/forum/topic/tcs-interview-question-about-cpuzzles-1
  2. What does int (*fun2())[4] and int (*fun3)[3][4] mean? Posted on Geeksforgeeks site http://geeksforgeeks.org/forum/topic/pointer-doubt
Answer for case 1, int *(*foo(int *arg))[4];
‘foo’ is function taking integer argument and returning pointer to array of integer pointers.
An example code,
#include

// Symbolic size
#define SIZE_OF_ARRAY (4)
// pointer to array of (SIZE_OF_ARRAY) integers
typedef int *(*p_array_t)[SIZE_OF_ARRAY];

// Declaration : compiler should throw error
// if not matched with definition
int *(*foo(int *arg))[4];

// Definition  : foo returning pointer to an
// array of integer pointers
p_array_t foo(int *arg)
{
    // array of integer pointers
    static int *arr[SIZE_OF_ARRAY] = {NULL};
   
    // return this
    p_array_t pRet = &arr;
   
    return pRet;
}

void main()
{}
Let us see the other two declarations.
CASE 1: int (*fun2())[4];
int (*fun2())[4];
fun2() - A function taking no arguments, returning a pointer to array of 4 integers.
Let us see how I came to this conclusion.
In C and C++, every declaration will contain one declarator and one or more declaration specifiers. In the current declaration 'fun2' is declarator (an identifier in program context) and 'int', '4' are declaration specifiers. Dropping the declarator leaves the type information. So, the following is type
int(*())[4];
The parenthesis binds to the declarator due to their precedence. Further, the type information can be reduced to,
int(*)[4];
It is now clear that the above declaration is pointer to array of 4 integers.
Finally, the identifier 'fun2' is "a function with no arguments and returning pointer to array of 4 integers".
CASE 2: int(*fun3)[3][4];
It is pretty simple from the above description.
int(*fun3)[3][4];
After dropping the declarator we left with,
int(*)[3][4];
which is pointer to array of array of integers (dimensions are obvious).
So, the identifier 'fun3' is "a pointer to array of array of integers".
For more information, read the documentation related to C and C++ programming language references on MSDN.

No comments: