Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are the parameters of this function?

void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

The return type is void* and proto_type is the name of the function? Or is this a pointer to function? Which are the parameters:

(long int, char *b) or this (const char *b, unsigned short int d)

Please, explain how this function works.

like image 834
user2679377 Avatar asked Aug 13 '13 17:08

user2679377


People also ask

Where is the parameter in a function?

Parameters are specified within the pair of parentheses in the function definition, separated by commas. When we call the function, we supply the values in the same way.

What is a parameter in a function example?

For example, if one defines a function as def f(x): ... , then x is the parameter, and if it is called by a = ...; f(a) then a is the argument. A parameter is an (unbound) variable, while the argument can be a literal or variable or more complex expression involving literals and variables.

Where is the parameter in a function Python?

A parameter is the variable listed inside the parentheses in the function definition. An argument is the value that is sent to the function when it is called.

Where are function parameters stored?

Parameter values to functions are stored on the stack as well, pushed immediately before the return address. Everything what lives on the stack (local variables, parameters etc.)


8 Answers

void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

This is a function declaration. The function name is proto_type, which takes two parameters of types:

  • long int
  • char *

and returns a pointer to a function which takes

  • const char*
  • unsigned short int

and returns void*.

Now if you use typedef, all of the above will becomes obvious:

typedef void* function_type(const char *b, unsigned short int d);

function_type* proto_type(long int, char *b);

Hope that helps.

like image 198
Nawaz Avatar answered Oct 05 '22 16:10

Nawaz


This declares proto_type as function taking (long int, char *) and returning pointer to a function taking a (const char *, unsigned short int) and returning a void pointer.

In other words:

typedef void * (*R)(const char *, unsigned short int);   // return type

R proto_type(long int, char *);
like image 39
Kerrek SB Avatar answered Oct 05 '22 18:10

Kerrek SB


I suggest bookmarking www.cdecl.org for the questions of this type. Beware, the page is a bit picky about what you type in (it doesn't accept parameter names at least).

like image 23
Tomek Avatar answered Oct 05 '22 18:10

Tomek


Start with the name of the function, then evaluate that using the usual expression syntax. Thus:

proto_type                  //  proto_type 
proto_type( long, char* )   //  is a function taking long, char*
                            //  (since function call has precedence over *
*proto_type( long, char* )  //  returning a pointer
(*proto_type(...))          //  (no change, but necessary for precedence reasons)
(...)( char const*, unsigned short )
                            //  to a function taking char const*, unsigned short
*(...)(...)                 //  returning pointer
void *(...)(...)            //  to void

(It's a little harder in cases where you don't have the name, like the type in a static_cast.)

like image 37
James Kanze Avatar answered Oct 05 '22 18:10

James Kanze


I will explain my process for parsing complex c-style declarations. I hope you will find it useful.

C-style parsing can be thought of as a right-to-left parsing starting at the identifier and bounded by parenthesis. So we start at the identifier proto_type

//       vvvvvvvvvv-------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

As we can see, moving right from proto_type, we immediately see a function call and some parameters, so that's easy. proto_type is a function that takes a long int and char* as parameters.

//                                   v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

Here we hit the first bounding parentheses, so we have to go backwards to find the next token which is here:

//      v----------------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

So now we know it returns a pointer to something. Now we have to look to the right again to find out what because of the bounding parentheses again

//     v--------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

Since we found another function call operator, the pointer it returns must be a pointer to a function that takes a const char* and an unsigned short int.

Finally, we reached another bounding parentheses, so move back left to find the return value of that function pointer.

//vvvv----------------------------------------------------------------------v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);

The function pointer returns a void* as the return value.

So to recap in English: proto_type takes a long int and a char* as parameters and returns a pointer to a function that takes a const char* and unsigned short int as parameters and returns a void*.

like image 26
Chris Cooper Avatar answered Oct 05 '22 16:10

Chris Cooper


proto_type is a function, which takes two arguments, long int and char *. It returns a function pointer that takes two arguments of type const char * and unsigned short int.

And to write this without using typedef is not very kind to the reader.

like image 35
Mats Petersson Avatar answered Oct 05 '22 18:10

Mats Petersson


Using VS2012 on Windows 8 x64.

proto_type is a function that takes a long int (which is unnamed) and an unsigned short int d, and returns a function of the form void * proto2(const char *b, unsigned short int d);

Here's some working code:

#include <stddef.h>

void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
void * proto2(const char *b, unsigned short int d);

int main(int argc, char** argv){
    if(proto_type(0, NULL)(NULL, 0) != (void*)8675309)
        return 0;
    else
        return 1;
}

void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d){
    return &proto2;
}

void* proto2(const char *b, unsigned short int d){
    return (void*)8675309;
}

What's going on is that main calls proto_type which returns a pointer to proto2, which main immediately calls. proto2 returns a magic pointer value that we check against in main.

Here's the debug output from VS2012:

The program '[3188] test.exe' has exited with code 1 (0x1).

As for "how this function works", the answer is however you want it to (assuming you're the one implementing it).

If you want another way to look at it, you want to read it inside to out for the order of which functions are called.

The lesson here is that C(++) function pointers are immensely opaque.

like image 24
EnticingCanine Avatar answered Oct 05 '22 18:10

EnticingCanine


I have done what @Tomek said and copied your prototype to http:www.cdel.org and then removed the parameter names from the prototype as:

    void * (*proto_type(long int, char *)) (const char *, unsigned short int );

pressed enter, and the web site returned:

declare proto_type as function (long int, pointer to char) returning pointer
to function (pointer to const char, unsigned short int) returning pointer
to void

Now, to translate this into carbon-unit speak: proto_type is declared as a function that takes a long int and a pointer to a char as parameters, it returns a pointer to a function that takes a pointer to a const char and an unsigned short integer and that function returns a void pointer.

Finally, a void pointer can be cast into a pointer to any other data type.

like image 35
JackCColeman Avatar answered Oct 05 '22 18:10

JackCColeman