What does this definition mean in C language? A pointer to what?
int *a();
int *a();
is the declaration of a function that takes an unspecified (but fixed) number of arguments and returns an int *.
It is different than:
int *a(void);
which is the declaration of a function that takes no argument and returns an int *.
The former declaration is an obsolescent feature, use the second form to declare a function with no parameter.
you can use the cdecl command by typing
explain int *a()
and you will get
cdecl> explain int *a()
declare a as function returning pointer to int
Related
When declaring a functions which takes function pointer as argument as mentioned below the compiler throws error.
void func_dec(int x, void(*)() funcptr);
Whereas it accepts below declaration,
void func_dec(int x, void(*funcptr)());
Why the compiler could not recognize the former declaration though it looks logical.
It is illegal because the formal definition in the language standard says so. As for the reason why it is that way, and it really may seem obscure, here it is:
From The New C Standard: An Economic and Cultural Commentary (v 1.2 from June 24, 2009, section 6.7 Declarations):
The intent of this syntax is for an identifier’s declarator to have
the same visual appearance as an instance of that identifier in an
expression. For instance, in:
int x[3], *y, z(void);
char (*f(int))[];
the identifier x might appear in the source as an indexed
array, y as a dereferenced pointer, and z as a function call. An
example of an expression using the result of a call to f is
(*f(42))[1].
And the same from The Development of the C Language by Dennis M. Ritchie:
Thus,
int i, *pi, **ppi;
declare an integer, a pointer to an integer, a
pointer to a pointer to an integer. The syntax of these declarations
reflects the observation that i, *pi, and **ppi all yield an int type
when used in an expression. Similarly,
int f(), *f(), (*f)();
declare
a function returning an integer, a function returning a pointer to an
integer, a pointer to a function returning an integer;
int *api[10], (*pai)[10];
declare an array of pointers to integers, and a pointer to
an array of integers. In all these cases the declaration of a variable
resembles its usage in an expression whose type is the one named at
the head of the declaration.
This is because,
void(*)() funcptr
is in invalid syntax on it's own.
Just supply the type while writing the function declaration,
void func_dec(int , void(*) ());
it should be enough. Otherwise, if you want to specify the variable name also, write
void func_dec(int x, void(*funcptr) ());
The function parameter name should go in the same place as the function name goes when you declare a function.
Function declaration:
void func(); // correct syntax
void() func; // incorrrect syntax
Function pointer declaration:
void (*func_ptr)(); // correct syntax
void (*)() func_ptr; // incorrect syntax
Declaring a function pointer becomes easier if you use the following trick:
Take the function declaration. Replace the function name with (*pointerName), or (*) if you want an unnamed version.
Example:
int func1(char* parm1); // function
int (*func1_ptr)(char* parm1); // function pointer
// function taking a function pointer as parameter:
void foo(int (*func1_ptr)(char*));
// The same declaration with an unnamed parameter:
void foo(int (*)(char*));
What is the type definition of a variable x in this code?
typedef int *f(int);
f *x;
f is an alias for a function type that takes int as an argument and returns an int*.
As such it isn't particularly useful.
(If you wanted f to be a pointer to a function that takes an int and returns an int, you'd have to write typedef int (*f)(int);)
typedef int* f(int);
type f is function with int parameters and returning pointer to int.
You cannot define a function using a typedef for a function type. please see the stack overflow answer.
This question already has answers here:
Writing a function pointer in c
(3 answers)
How do you read C declarations?
(10 answers)
Closed 8 years ago.
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);
}
.
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.
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)
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
According to cdecl, foo is:
declare foo as function (int) returning pointer to function (int) returning int
To declare a function pointer using typedef, it will be something like:
typedef void (*FOO)(int i)
But normally the syntax for typedef is like:
typedef int BOOL
so why is the first one not:
typedef void (*)(int) FOO
To return a function pointer (without typedef), the syntax is as follow:
void (*foo(char c))(int)
which means foo takes in a char and returns a pointer to a function which takes an int and returns nothing. The syntax is so weird! It looks like foo takes in an int and returns nothing. The parentheses don't seem to be in the right places. If it is to return a function pointer, why is it not something like:
(void (*)(int)) foo(char c)
which is very straightforward. I am really having trouble understanding the syntax here, let alone using it. Can someone please explain what's going on here?
An integer is just:
int x;
A name for the above is given by:
typedef int x_type;
A pointer to an int is:
int *p;
It's type would be:
typedef int *p_type;
A function called foo taking a double``and returning anint` is:
int foo(double);
Defining the type of foo would be:
typedef int foo_type(double);
Now a pointer to the above should take an *, but () (function call) binds tighter than * (dereference), so parentesis:
typedef int (*ptr_to_foo_type)(double);
This might be better written:
typedef foo_type *ptr_to_foo_type;
as some suggest writing for clarity.
The idea is that the type description looks (somewhat) like its use. Badly mangled idea, given prefix/postfix operators, that much everybody agrees on. But it is now much too late to change.
Declaration syntax is based on the types of expressions, not objects. Another way of saying it is that "declaration mimics use".
Let's start with a simple pointer expression; call it iptr. iptr points to an integer value. If we want to access that value, we need to dereference iptr with the unary * operator, like so:
x = *iptr;
The expression *iptr has type int, so the declaration of iptr is written
int *iptr;
If you wanted to create a typedef for an int pointer, you would add the typedef to get
typedef int *iptr;
iptr now serves as a synonym for type "pointer to int", so you can write
iptr ip;
which declares ip as a pointer to int (as a rule, you really don't want to hide pointers in typedefs).
Now let's say you have a pointer to a function that takes two int arguments and returns an int value, call it fp. To call the function, you dereference the pointer and pass the necessary arguments to the resulting function, like so:
x = (*fp)(arg1, arg2); // C allows you to omit the * in the call, so you could
// also write it as simply x = fp(arg1, arg2), but we're
// leaving it in so the following explanation makes sense
The function call () operator has higher precedence than unary *; *fp() will be interpreted as *(fp()), which is not what we want. To dereference fp before calling the function it points to, we must explcitly group the * operator with fp.
The type of the expression (*fp)(arg1, arg2) is int, so the declaration of fp becomes
int (*fp)(int arg1, int arg2);
Let's look at your second example now: foo is a function that takes a char argument and returns a pointer to a function that takes an int argument and returns void. You'd call it as something like
(*foo(c))(x);
Again, the type of the expression (*foo(c))(x) is void, so it follows that the declaration is
void (*foo(char c))(int x);
For syntactic reasons, typedef is treated as a storage class specifier like extern or static, although it has a very different meaning. It doesn't change the structure of a declaration; it just changes how that declaration is interpreted by the compiler. Adding typedef to the above, as in
typedef void (*foo(char c))(int x);
now creates the synonym foo for the type "function returning pointer to function returning void". It's no different from how simpler type definitions like
typedef int *iptr;
behave.
1) The syntax for typedef is to take a declaration of a variable of that type and put typedef in front of it.
2) The syntax for declarations echos the syntax for actually obtaining a value of that type. See my other recent answers regarding precedence of addressing operators (including function call), such as (*twod)[3] vs *(twod)[3] C Pointers ... I'd rather not repeat it all again.
What does this do?
int *(*pfp) ();
int *(*pfp) ();
Creates a pointer to a function that returns int*. The function pointer name ispfp.
Here's an example:
int* myFunc(void)
{
return NULL;
}
int main(int argc, char**argv)
{
int *(*pfp) (void);
pfp = myFunc;
return 0;
}
Note: Since the parameters of the function pointer is not (void) that you gave, that means that the parameter list is not specified in C. In C++ it would mean that it's a function with no parameters exactly.
Brian's explained the "what", but if you're curious as to the why, here's an excerpt from Dennis Ritchie's The Development of the C Language:
The second innovation that most clearly distinguishes C from its predecessors is this fuller type structure and especially its expression in the syntax of declarations. NB offered the basic types int and char, together with arrays of them, and pointers to them, but no further ways of composition. Generalization was required: given an object of any type, it should be possible to describe a new object that gathers several into an array, yields it from a function, or is a pointer to it.
For each object of such a composed type, there was already a way to mention the underlying object: index the array, call the function, use the indirection operator on the pointer. Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear. Thus,
int i, *pi, **ppi;
declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects the observation that i, *pi, and **ppi all yield an int type when used in an expression. Similarly,
int f(), *f(), (*f)();
declare a function returning an integer, a function returning a pointer to an integer, a pointer to a function returning an integer;
int *api[10], (*pai)[10];
declare an array of pointers to integers, and a pointer to an array of integers. In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration.
For more info, read Steve Friedl's "Reading C type declarations" or Eric Giguere's "Reading C Declarations: A Guide for the Mystified".
pfp is a pointer to a function that takes no parameters (or indeterminate parameters in C) and returns a pointer to an int.
Using the 'clockwise-spiral' rule is an effective way to decipher complex C declarations (at least I find it effective):
http://c-faq.com/decl/spiral.anderson.html
Use http://www.cdecl.org/ for these things, if you're not sure.