I'm confused about the meaning of void *function().
Is it a pointer to function or a function returning void*? I've always used it on data structures as a recursive function returning a pointer, but when i saw a code in multithreading (pthread) there is a same function declaration. Now I'm confused what's the difference between them.
The function has the return type void *.
void *function();
So I always prefer in such cases to separate the symbol * from the function name like
void * function();
And as Jarod42 pointed to in a comment you can rewrite the function declaration in C++ using the trailing return type like
auto function() -> void *;
If you want to declare a pointer to function then you should write
void ( *function )();
where the return type is void Or
void * ( *function )();
where the return type void *.
Or a pointer to function that returns pointer to function
void * ( *( *function )() )();
Whenever I'm unsure about C syntax issues, I like to use the cdecl utility (online version) to interpret for me. It translates between C syntax and English.
For example, I input your example of void *foo() and it returned
declare foo as function returning pointer to void
To see what the other syntax would look like, I input declare foo as pointer to function returning void and it returned
void (*foo)()
This gets particularly useful when you have multiple levels of typecasts, stars, or brackets in a single expression.
It is a function returning a pointer to void.
Think of your declaration this way:
void *(function());
This would be a function returning void (or nothing):
void (*function2)();
Think of the above declaration this way:
void ((*function2)());
A much easier way to write these is to use typedefs:
typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();
function_returning_void_pointer function;
function_returning_nothing *function2;
This generally eliminates the confusion around function pointers and is much easier to read.
Declarations in C/C++ are read from the identifier outwards following operator precedence.
A quick look at the C/C++ operator precedence table in wikipedia reveals that the function call operator () has a higher precedence than the indirection operator *. So, your function declarations reads like this:
Start at the identifier: function is
function() a function that takes no arguments
void* function() and returns a void*.
This general principle also holds with array declarations ([] also has higher precedence than *) and combinations of the two. So
int *(*arr[42])();
is read as
arr is
arr[42] an array of 42 elements which are
*arr[42] pointers to
(*arr[42])() functions that take no arguments and
int *(*arr[42])() return an int*.
It takes a bit to get used to this, but once you've understood the principle, it's easy to read those declarations unambiguously.
Related
I'm thinking about the difference between:
void *signal(int, void (*)(int))(int)
and
void (*signal(int, void (*)(int)))(int)
I know the latter is from here - Example #3: The ``Ultimate'' (it's a hilarious learning experience when I was trying speak out loud to understand it):
signal is a function takes (int, void (*)(int)) as input and returns a pointer to another function that takes (int) and returns void.
For the former I'm thinking that since the last (int) will have higher precedence than * so it should be a syntax error, but from cdecl.org the result is:
["] declare signal as function (int, pointer to function (int) returning void) returning function (int) returning pointer to void [."]
So I need a check.
One has to differentiate between grammar and semantics. cdecl.org only gives you the grammatical meaning of whatever declarator you type into it. In your first example, you have indeed a grammatically correct declaration of signal as a function returning a function. However, C does not allow functions to return other functions:
N1570 6.7.6.3 §1:
A function declarator shall not specify a return type that is a function type or an array type.
So while this declaration is grammatically correct, it is semantically invalid. In other words: While the C syntax makes it possible to write "function returning a function", you're not allowed to actually have a function that returns a function in a program. Just like the English language (or any language for that matter) also allows you to express all sorts of thoughts that would physically be impossible to carry out…
The most important part here is... you don't need to learn this, it is a very poorly designed part of the language. You can scroll down to the bottom of the answer to find the sane, professional solution.
Otherwise, if you insist, it goes like this...
When trying to return a function pointer from a function, the type of the function pointer gets split up. If you want to return a function pointer void(*)(void), then this poor function pointer gets split up in 3 parts. Lets call them like this:
void is A, the return type of the pointed-at function.
(*) is B, marking this a pointer to function, rather than a function.
(void) is C, the parameters of the pointed-at function.
Then if we want to stick this as a return type into some other icky function declaration, they end up like this:
#define A void
#define B *
#define C (void)
// A (B) C equals void(*)(void)
A (B madness(int, void (*fp)(int))) C;
where A, B and C are the parts of our poor function pointer to be returned, madness is the name of the function, and the rest is some mess used as parameters by the function itself.
If we omit the B part, it will be interpreted like a function returning another function of type void f (void); which isn't valid. The syntax allows it but not the language specification.
Similarly, int foo (void) [3]; - a function returning an array, is not allowed either.
Pondering these things is the road to madness and it makes the code unreadable. Professional programmers use typedef.
Given
void (*madness(int, void (*f)(int)))(int);
replace it with:
typedef void func_t (int);
func_t* sanity (int, func_t* f);
I am trying to understand what this means, the code I am looking at has
in .h
typedef void (*MCB)();
static MCB m_process;
in .C
MCB Modes::m_process = NULL;
And sometimes when I do
m_process();
I get segmentations fault, it's probably because the memory was freed, how can I debug when it gets freed?
It defines a pointer-to-function type. The functions return void, and the argument list is unspecified because the question is (currently, but possibly erroneously) tagged C; if it were tagged C++, then the function would take no arguments at all. To make it a function that takes no arguments (in C), you'd use:
typedef void (*MCB)(void);
This is one of the areas where there is a significant difference between C, which does not - yet - require all functions to be prototyped before being defined or used, and C++, which does.
It introduces a function pointer type, pointing to a function returning nothing (void), not taking any parameters and naming the new type MCB.
The typedef defines MCB as the type of a pointer to a function that takes no arguments, and returns void.
Note that MCB Modes::m_process = NULL; is C++, not C. Also, in C, the typedef should really be typedef void (*MCB)(void);.
I'm not sure what you mean by "the memory was freed". You have a static pointer to a function; a function cannot be freed. At most, your pointer has been reset somewhere. Just debug with a memory watch on m_process.
Let's take an example
typedef void (*pt2fn)(int);
Here, we are defining a type pt2fn. Variables of this type point to functions, that take an integer as argument and does not return any value.
pt2fn kk;
Here, kk is a variable of type pt2fn, which can point to any function that takes in an integer as input and does not return any value.
Reference:https://cs.nyu.edu/courses/spring12/CSCI-GA.3033-014/Assignment1/function_pointers.html
It's a function pointer. You get a SEGMENTATION FAULT because you are trying to make a call to a function which address is invalid (NULL).
According to your specific sample, the function should return no value (void) and should receive no parameters ().
This should work:
void a()
{
printf("Hello!");
}
int main(int arcg, char** argv)
{
m_process = a;
m_process(); /* indirect call to "a" function, */
// Hello!
}
Function pointers are commonly used for some form of event handling in C. It's not its only use though...
I am looking at some late 80's C code. I have the following definition.
void (*_flush())(){ /* body ommitted */ }
I believe this is a function, _flush , with void as its argument list and returns a function pointer that returns void and has void as its argument list.
The equivalent in two parts:
typedef void (*funcptr)(void);
functptr flush(void){ /* body ommitted */ }
Do I understand the old notation correctly?
Yes, your understanding is (almost) correct:
cdecl> explain void (*_flush())()
declare _flush as function returning pointer to function returning void
It's not correct to say that your function has void as its argument list, though. A function like:
void func()
Doesn't take no arguments, it takes an unspecified number of arguments. You could call it in whichever of these ways is appropriate:
func()
func(a);
func(a, b, c);
and so on. If the implementation of _flush doesn't make use of any parameters, you can probably safely use void as you suggest, but your example doesn't include enough information to say.
A good reference: C function with no parameters behavior
Use http://www.cdecl.org/ to get an nice translation of your function.
void (*_flush())()
declare _flush as function returning pointer to function returning void
Had the definition of function _flush() used any parameters itself, they would have been listed between the last ) and { so we can be confident that the function _flush takes no arguments.
void (*_flush())() { /* body omitted */ }
//----------------^
The return value of flush is itself a function, let's call it foo
void foo(...)
declare foo as function returning void
Here it is known that the function returns void, but its parameter list could be of any number of parameters and of any number of any type. Just not known from the info given but likely discernible from the body of _flush.
The code I am using has this statement:
typedef void ( udp_data_notify )(OS_FIFO * pfifo, WORD port);
This looks like a declaration of a function pointer for udp_data_notify, however there is no *. Can it still be a function pointer without an asterisk?
Here is a statement that uses udp_data_notify:
void RegisterUDPFifoWithNotify( WORD dp, OS_FIFO *pnewfifo , udp_data_notify * nudp)
Any help as to what is happening would be appreciated!
A typedef such as:
typedef void name(int);
(the parenthesis around name are redundant) will define name as the type of a function, not a function pointer. That would be:
typedef void (*pname)(int);
You are probably wondering what they are good for. Well, function types are not very useful, other than for declaring pointers:
name *pointer_to_function;
And that can be made arguably more readable with the other typedef:
pname pointer_to_function;
That's because you cannot define a variable of type function. If you try, you will simply write the prototype of a function, but in a quite obfuscated syntax:
name foo; //declaration (prototype), not variable
void foo(int x) //definition
{
}
But note that you cannot use the typedef to define the function:
name foo {} //syntax error!
As already said, the typedef declares an alias for function type. When you want to use it to declare a function pointer, an asterisk is required (udp_data_notify* x). A declaration without the asterisk (udp_data_notify x) would be a function declaration, except in one special case. When used in a parameter a function type is automatically turned into the corresponding function pointer type:
typedef void F(void);
void foo(F a, F* b) // special case; a and b are both function pointers
{
F c; // function declaration
F* d; // function pointer
}
The typedef you show declares udp_data_notify to be an alias for a function type. Then the parameter declaration udp_data_notify *nudp declares nudp to be a pointer to a function of that type. There is no function call here.
Regarding the function-call operator (postfix ()), the expression that designates the called function must be a pointer to a function. When you call a function normally, without a pointer, such as sqrt(2), the function is automatically converted to a pointer for you. So sqrt(2) is actually (&sqrt)(2). When you call a function with a pointer, the call is in the right form already.
I need to declare an array of pointers to functions like so:
extern void function1(void);
extern void function2(void);
...
void (*MESSAGE_HANDLERS[])(void) = {
function1,
function2,
...
};
However, I want the the array to be declared as constant -- both the data in the array and the pointer to the data. Unfortunately, I do not recall where to place the const key-word(s).
I'm assuming the actual pointer, MESSAGE_HANDLERS in this case, is already constant because it is declared as an array. On the otherhand, couldn't the function pointers within the array be change at runtime if it is declared as shown?
There is a technique to remember how to build such type. First try to read pointers starting from their name and read from right to left.
How to declare that stuff without help?
Arrays
T t[5];
is an array of 5 T. To make T a function type, you write the return-type to the left, and the parameters to the right:
void t[5](void);
would be an array of 5 functions returning void and taking no parameters. But functions itself can't be stuffed in arrays! They are not objects. Only pointers to them can.
What about
void * t[5](void);
That's still wrong as it would just change the return-type to be a pointer to void. You have to use parentheses:
void (*t[5])(void);
and this will actually work. t is an array of 5 pointers to functions returning void and taking no parameters.
Great! What about an array of pointers to arras? That's very similar. The element type appears at the left, and the dimension at the right. Again, parentheses are needed because otherwise the array would become a multidimensional array of integer pointers:
int (*t[5])[3];
That's it! An array of 5 pointers to arrays of 3 int.
What about functions?
What we have just learned is true about functions too. Let's declare a function taking an int that returns a pointer to another function taking no parameter and returning void:
void (*f(int))(void);
we need parentheses again for he same reason as above. We could now call it, and call the returned function pointed to again.
f(10)();
Returning a pointer to function returning another pointer to function
What about this?
f(10)(true)(3.4);
? In other words, how would a function taking int returning a pointer to a function taking bool returning a pointer to a function taking double and returning void would look like? The answer is that you just nest them:
void (*(*f(int))(bool))(double);
You could do so endless times. Indeed, you can also return a pointer to an array just like you can a pointer to a function:
int (*(*f(int))(bool))[3];
This is a function taking int returning a pointer to a function taking bool returning a pointer to an array of 3 int
What does it have to do with const?
Now that the above explained how to build up complexer types from fundamental types, you can put const at places where you now know where they belong to. Just consider:
T c * c * c ... * c name;
The T is the basic type that we end up pointing to at the end. The c stands for either const or not const. For example
int const * const * name;
will declare name to have the type pointer to a constant pointer to a constant int. You can change name, but you cannot change *name, which would be of type
int const * const
and neither **name, which would be of type
int const
Let's apply this to a function pointer of above:
void (* const t[5])(void);
This would actually declare the array to contain constant pointers. So after creating (and initializing) the array, the pointers are const, because the const appeared after the star. Note that we cannot put a const before the star in this case, since there are no pointers to constant functions. Functions simply can't be const as that would not make sense. So the following is not valid:
void (const * t[5])(void);
Conclusion
The C++ and C way of declaring functions and arrays actually is actually a bit confusing. You have to get your head around it first, but if you understand it, you can write very compact function declarations using it.
In situations like this, do a typedef to name your function signature, that makes it far simpler:
typedef void MESSAGE_HANDLER(void);
with that in place, it should be just:
MESSAGE_HANDLER * const handlers[] = { function1, function2 };
To get the actual content of the array constant.
EDIT: Removed pointer part from the typedef, this really is better (live and learn).
cdecl says:
cdecl> explain void (* const foo[])(void)
declare foo as array of const pointer to function (void) returning void
Is it what you need?
With VisualStudio 2008, I get:
void (* const MESSAGE_HANDLERS[])(void) = {
NULL,
NULL
};
int main ()
{
/* Gives error
'=' : left operand must be l-value
*/
MESSAGE_HANDLERS = NULL;
/* Gives error
l-value specifies const object
*/
MESSAGE_HANDLERS[0] = NULL;
}
I am not sure if this will work in 'C'. it does work in 'C++':
First define MESSAGE_HANDLERS as a type:
typedef void (*MESSAGE_HANDLER)();
Then, use the type definition to declare your array a constant:
MESSAGE_HANDLER const handlers[] = {function1, function2};
The trick is in the typedef, if you can do the same semantically in 'C', it should work too.