7_R3X 7_R3X - 3 months ago 8
C Question

Meaning of int in this expression

I could not understand what exactly does the innermost "int" mean in the following syntax.



int(*(*ptr (int))(void)




My understanding of this expression says that
ptr
is a function pointer takes nothing for its argument( from the void part of the expression) and returns an
int
(from the
int
in the beginning). But what does the
int
after
ptr
mean?

Edit : Apologies but the question in the question paper itself was misprinted. Here's the expression

int (*ptr (int))(void)

Answer

From the C standard, the signal() function has the rather complex signature:

void (*signal(int sig, void (*func)(int)))(int);

The signal() function takes two arguments, an int and a pointer to a function that takes an int argument and returns void; it returns a pointer to a function that takes an int argument and returns void — the same type as its second argument.

This is more complex than your code, but it can be reduced to your example, which is:

int (*ptr(int))(void);

Working step by step:

void (*signal(int sig, void (*func)(int)))(int);
void (*signal(int sig))(int);  // Remove second argument
void (*signal(int))(int);      // Remove argument name
int  (*signal(int))(int);      // Change return type
int  (*ptr(int))(int);         // Change name of function
int  (*ptr(int))(void);        // Remove argument of returned pointer to function

So, in context, it means that your statement is a declaration that ptr is a function that takes an int argument and returns a pointer to a function that takes no argument and returns an int value. The implementation (definition) of the function will give an argument name to the inner int.

Example code — with ptr renamed to function:

#include <stdio.h>
#include <stdlib.h>

static int counter(void) { static unsigned short val = 0; return ++val; }

static int (*function(int arg))(void)
{
    switch (arg)
    {
    case 0:
        return rand;
    default:
        return counter;
    }
}

int main(void)
{
    int (*func)(void);

    func = function(0);
    printf("F() = %5d\n", func());
    printf("F() = %5d\n", func());
    printf("F() = %5d\n", func());

    func = function(1);
    printf("F() = %5d\n", (*func)());
    printf("F() = %5d\n", (*func)());
    printf("F() = %5d\n", (*func)());

    return 0;
}

Example output:

F() = 16807
F() = 282475249
F() = 1622650073
F() =     1
F() =     2
F() =     3

I'm assuming I could add assert(sizeof(unsigned short) != sizeof(int));.

Comments