Unknown function signature in C - c

I would be very thankful if you could explain me what the following means:
void bar(char *a, char *b, unsigned short c) // (2)
{
...
}
void (*foo(void))(char *, char *, unsigned short) // (1)
{
return bar;
}
In particular,
Why there are no variable names in (1)?
What does void (*foo(void)) mean? How can *foo(void) be a name?
What does return bar mean? Returns it the address of the bar source code, or the result from bar, or else?
Is there any feature in making these signatures so complicated?
Could you give an example of the usage?

foo is a function that takes no arguments and returns a pointer to a function that takes three arguments of types char *, char * and unsigned short and returns void.
These declarations can be quite confusing because they should be read inside-out, bouncing left and right as needed:
foo is a thing ...
foo(void) ... apparently a function
*foo(void) ... whose return value can be dereferenced
(*foo(void))(...) ... and then called with these arguments
void (*foo(void))(...) ... which results in a value of type void.
You can also use cdecl.org to parse complex declarations for you:
declare foo as function (void) returning pointer to function (pointer to char, pointer to char, unsigned short) returning void
Usage examples:
// Immediately call the returned function.
// The similarity to the declaration is no coincidence!
(*foo())("hello", "world", 42);
// Store the returned function pointer for later invocation.
// This time there are no parentheses following the name, because
// this is a variable, not a function.
void (*fnPtr)(char *, char *, unsigned short) = foo();
(*fnPtr)("hello", "world", 42);
Argument names can always be omitted if the arguments aren't used inside the function. In this case, there isn't even a function body to use them in, because the body of foo isn't what the arguments are being passed to.

Related

Invalid type of arguments C

I am trying to implement a function that read lines from a file and put them into a string array. But it gives me the warning:
expected char ** But argument is of type char * (*)[(sizetype)(numberOfchar)]
It was working on Windows but when I switch into Linux it stops working.
Here is the caller and the array variable :
char *hashes[numberOfchar];
PutInArray(textName, numberOfchar, &hashes);
And here is the function (the void* is for the next part of the program, threading) :
void* PutInArray(char* k, int d, char *tab[d]) {
FILE* fp = NULL;
int i;
fp = fopen(k, "r");
if(fp != NULL) {
for (i = 0; i < d; i++) {
tab[i] = (char *)malloc((34) * sizeof(char));
fgets(tab[i], 34, fp);
}
fclose(fp);
}
}
Let's see how function calls work for other types.
You have a variable int v; and a function void foo(int x) (the variable declaration and the parameter declaration look the same). You call foo(v). You also have a function void bar(int* x) (the variable declaration has one star less than the parameter declaration). You call bar(&v).
You have a variable int* v; and a function void foo(int* x) (the variable declaration and the parameter declaration look the same). You call foo(v). You also have a function void bar(int** x) (the variable declaration has one star less than the parameter declaration). You call bar(&v).
You have a variable const struct moo ***v and a function void foo(const struct moo ***x) (the variable declaration and the parameter declaration look the same). You call foo(v). You also have a function void bar(const struct moo ****x) (the variable declaration has one star less than the parameter declaration). You call bar(&v).
You have a variable char *hashes[numberOfchar] and a function void* PutInArray(char* k, int d, char *tab[d]). The variable declaration and the parameter declaration still look the same. Why on God's green earth stick & in front of the variable?
I hear you saying "but I want to pass hashes by reference, and to pass by reference I need to use &". Nope, arrays are automatically passed by reference (or rather an array automatically gets converted to a pointer of its first element; parameters of array type are similarly adjusted so that the rule formulated above just works).
For completeness, the analogue of bar would have a parameter that looks like this:
char* (*tab)[numberOfchar]
and if you had such parameter, you would have to use &hashes. But you don't need it.
Your code is almost OK. Concerning the error/warning you get, just write PutInArray(textName, numberOfchar, hashes) instead of PutInArray(textName, numberOfchar, &hashes) for the following reason:
In function PutInArray(char* k, int d, char *tab[d]), char *tab[d] has the same meaning as char*[] and char**, i.e. it behaves as a pointer to a pointer to a char.
Then you define hashes as char *hashes[numberOfchar], which is an array of pointers to char. When using hashes as function argument, hashes decays to a pointer to the first entry of the array, i.e. to a value of type char **, which matches the type of argument tab. However, if you pass &hashes, then you'd pass a pointer to type char *[], which is one indirection to much. (BTW: passing &hashes[0] would be OK).
BTW: PutInChar should either return a value or should be declared as void PutInArray(char* k, int d, char *tab[d]) (not void*).

Passing a void value function as part of a function signature in C

First off I'm primarily a Java programmer, but I've been tasked with doing some network stuff in C. I've got a function with the following signature:
foo(int, void (*) (int, char *, int))
It's the void (*) that's throwing me for a loop. This is supposed to call another function (static)
bar(int, char *, int)
Now am I right in thinking that foo wants a pointer to bar with whatever variables I need at the time?
Calling
foo(1,myfunction(1,&anCharArray,10));
fails with a number of errors.
If anyone has any links to good articles on pointers that would also help.
foo(1,myfunction(1,&anCharArray,10))
fails with a number of errors.
Try instead:
foo(1, myfunction)
The second parameter of foo function is a function pointer but you were passing the return value of a function call.
The void (*)(int, char *, int) is an anonymous parameter of type 'pointer to function returning void and taking three arguments: an int, a char * and another int'. You need to pass the name of such a function (in your case, bar) as the second argument to the function foo. Personally, I'd prefer to see the declaration of foo written with a return type and names for parameters, and the declaration of bar() should also have a return type and names for the parameters. The names do not have to match between function declaration and definition, but it is not usually regarded as good style to vary the names between them.
void foo(int num, void (*func)(int num, char *str, int len));
static void bar(int num, char *str, int len);
You can then call:
foo(10, bar);
Inside foo(), you will have code such as:
void foo(int num, void (*func)(int num, char *str, int len))
{
char str[] = "Supercalifragilisticexpialidocious";
(*func)(num, str, strlen(str));
}
Or, if you're new school (not an archaic relic like me), then:
void foo(int num, void (*func)(int num, char *str, int len))
{
char str[] = "Supercalifragilisticexpialidocious";
func(num, str, strlen(str));
}
These are equivalent. I still prefer the explicit "I'm calling a function via a pointer to function" notation, but it isn't necessary and modern style tends to avoid it.

Is main with parameter list of void different from main with an empty parameter list? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is the type of the main function in C and c++ left to the user to define?
What is a void ? Anyone provide some examples, proper use of void ? And what is the difference when we write void main (void) or main() ?
In C, in general, (void) means no arguments required in function call, while () means unspecified number of arguments.
e.g.
void foo(void)
{
// body
}
void bar()
{
//body
}
In calling enviroment,
foo(); // Correct
foo(1); // Incorrect
bar(); // Correct
bar(1); // Also correct
This was the general explanation.
But for your case for main() , C99 Standard says that,
5.1.2.2.1 Program startup
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or
with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char *argv[]) { /* ... */ } or equivalent;
or
in some other implementation-defined manner.
So, in this void main(void) return type should be int.
And at last , for main(),
return type is not given so implicitly return type would be int.
Excluding the return type of the main as in
main(){
}
doesn't mean that it's a void type, it depends on the compiler. I think it can be said it's generically interpreted as
int main(){
}
The void type tells the compiler that there is no 'entity' (no 'storage'), so
void func(int i)
takes an int but returns nothing. In the case of parameters this:
void func()
is equivalent to this:
void func(void)
which indicates more explicitly that it does not take parameters.
Different story is with the type void * which is a type, a pointer to something dimensionless.
Basically, void is a data type, which basically used with method declaration. It means nothing or no type. Eg:
1) int myFunc(void) -- the function takes nothing.
2) void myFunc(int) -- the function returns nothing
3) void* data; -- 'data' is a pointer to data of unknown type, and cannot be dereferenced
Void means "emptyness". In your example of void main() it means that the functions main() does not return a value. I feel obliged tell you that void main() should be avoided (no pun intended) at all costs, use int main() instead. int main() makes sure your program can return a value of type int to the OS on close. There are numerous other uses of void, check out this website if you want to read more about this.
void is a data type with no values. It is also an incomplete data type that cannot be completed. When used as a return type for a function, it indicates that the function does not return a value:
void foo(int x);
When used as a parameter list, it indicates that the function takes no arguments:
void bar(void);
This is different from an empty parameter list, which indicates that the function takes an unspecified number of arguments (in C; in C++, an empty parameter list is the same as using void):
void bletch();
No object (variable) can be typed void. However, you can declare pointers of type void *: these are "generic" pointers, and can be converted to and from other pointer types without an explicit cast. The standard memory allocation functions malloc, calloc, and realloc all return void *:
double *darr = malloc(sizeof *darr * rows);
In a hosted implementation (basically, anything with an operating system), main must be declared as
int main(void)
or
int main(int argc, char **argv) // the parameter names can be whatever you want,
// but argc and argv are the usual convention;
// char **argv is equivalent to char *argv[]
or in some other implementation-defined manner; an implementation may accept
void main()
as a legitimate signature for main, but it must explicitly document that somewhere.

How do I declare a function to be used as a function pointer in c?

I am confused with function pointer declaration.
I have an api abc() which takes an argument as so:
void abc(void (*my_func)(void *p), int, int)
If I want to pass my function as an argument to that api, I am declaring it in my .h file:
void (*xyz)(void *p)
and defining as:
void *(xyz)(void *p){
statements;
}
but this throws an error. Please correct me.
you just need to declare it:
void xyz(void *p);
with the implementation the same way.
When you pass it into your api, the type system figures out it out automatically:
abc(xyz,someint,anotherint);
The (*xyz) means that it is a function pointer.
Function pointers are best handled with typedefs. So it is guaranteed that there is nothing wrong.
I would do the following:
// define a type for the function (not its pointers, as you can often read)
typedef void my_func_t(void *p);
void abc(my_func_t*, int, int);
// declaration in order to be type-safe - impossible if only the pointer would be typedef'd
my_func_t my_func_impl;
// definition:
void my_func_impl(void *p)
{
do_something_with(p);
}
and then you can call your abc() with abc(my_func_impl, 47, 11). You can put a & before my_func_impl there in order to point out that it is the function address you wish to obtain, but it is optional.
An alternative would be to write
typedef void (*my_func_p)(void *p);
and use my_func_p instead of my_func_t *, but this has the disadvantage that you cannot write my_func_t my_func_impl;.
Why would you want to do that?
Well, if, by any coincidence or accident, the function definition or the typedef is changed, they won't match any longer, but the collision is not declared as error, but only as warning (Mismatch pointer). OTOH, my_func_t my_func_impl; serves as a kind of prototype, which causes a function header mismatch, which is an error.
Simply declare and define your function as you would any other:
void xyz(void *p);
void xyz(void *p){
// ...
}
and pass a pointer to the API:
abc(xyz, 42, 7);
Function names are automatically interpreted as function pointers where appropriate. You can also explicitly take the address of the function, if brevity isn't your thing:
abc(&xyz, 42, 7);
If I understood correctly, you want xyz to be the function that is passed to abc, right?
As the argument my_func indicates, you have a pointer to a function that takes void * as argument and returns void
type (*func_pointer)(type, type, type, .......)
^ ^ ^ ^ ^ ^
| | | | | |
| | | argument types
| | pointer name
| This is a function pointer
return type
Therefore, you need to declare xyz as:
void xyz(void *p);
And the same in implementation:
void xyz(void *p){
statements;
}
What you are doing wrong is that, the line you wrote in the .h file defines a function pointer, named xyz. The function pointer has no value, because you never wrote xyz = some_function;
What you have written in the source file is a function, also with name xyz that takes a void * as input and returns a void *, instead of void which was your intention.
Maybe this helps you get less confused:
When you write int *x;, x is a pointer to int. Then you can have int y; that doesn't have an extra * and write x = &y;.
It's the same with functions. If you have void (*funcptr)(void *p);, then all you need is a function that says void some_func(void *p){} (again without the extra *) and write funcptr = some_func;. You don't need the & since function names are in fact pointer to the function. You could put it to be more explicit though.
The first argument of 'abc' is the pointer of function returning 'void' and having 'void *' as an argument...
So your code should look like:
void
myFunc (void *)
{
// ... my statements
}
...
abc (myFunc, 10, 20);
This works
void abc(void* (*my_func)(void*), int a, int b) {
my_func(0);
}
void *(xyz)(void *p) {}
int main() {
abc(xyz, 0, 0);
return 0;
}
When you write void (*my_func)(void *p) it means pointer to function, that returns void
And void (*my_func)(void *p) it means pointer to function, that returns pointer

Strange C construction encountered in academic paper

The code states:
void (* log_msg)(char *msg)
=printf;
void change_and_log(int *buffer, int offset, int value){
buffer[offset] = value;
log_msg("changed");
}
I'm most concerned with the first part:
Firstly, what does the signature void (* log_msg)(char *msg) mean? Is this code simply mapping the function log_msg to printf? In that case, why is the function name (* log_msg) and not simply log_msg?
void (* log_msg)(char *msg) is actually a function pointer. You could view this as
typedef void (*LoggerFunctionPointer)(char* msg);
LoggerFunctionPointer log_msg = printf;
Yes, it maps log_msg to printf, but no, log_msg isn't a function, but a pointer that points to a function printf.
Using a function pointer has the advantage that the log_msg can be switched at runtime. For example, you could provide a switch in the interface that
void no_log_msg(char* msg) {}
...
if (enable_debug) {
log_msg = printf;
} else {
log_msg = no_log_msg;
}
then, without changing other source code, all logging can be inhibited.
(BTW, the sample code is incorrect because the signature of printf is int printf(const char*, ...). To avoid the implicit cast, log_msg should be declared as
int (*log_msg)(const char*, ...) = printf;
)
It's a function pointer.
The type of a function pointer is R (*)(Args...), where R and Args... are replaced with the return type and arguments, if any. It is read as "a pointer to a function that takes arguments Args... and returns R."
Your code would read easier as:
// print_function is a type that is a function pointer
typedef void (*print_function)(char *msg);
// log_msg is a variable of the type print_function: it points to a function
print_function log_msg = printf; // point to printf
And later, it's just calling that function via a function pointer.
The top two lines are establishing a function pointer (hence the *), the function is named log_msg, and it's then set to point to printf - after which a call to log_msg ends up calling printf.
log_msg is a function pointer, in particular a "pointer to a function taking a char * and returning void". In this case it's just used as an alias for printf (but could point to any function with the same arguments and return type).
The syntax for function pointers in C can be pretty intimidating at first.

Resources