What does (*) mean in plain C? - c

I can't get the meaning of the "(*)" expression in the following statement:
#define PySpam_System \
(*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])
where
#define PySpam_System_NUM 0
#define PySpam_System_RETURN int
#define PySpam_System_PROTO (const char *command)
(excerpt from http://docs.python.org/2/extending/extending.html). What could that mean? (Excuse me for a dumb question). Resembles a function pointer, but with a very confusing syntax.
UPDATE: Thanks to Shahbaz and Jonathan things are getting mostly clear, but I still can't get two nuances:
Why const char *command, not just const char *. I thought that the name of the argument should be omitted in function pointer type declaration and type conversion? So it must not be omitted, but rather just can be?
Why (*(int (*)(const char *command)), not just (int (*)(const char *command)? What's the purpose of the outer (*[everything else here])? It's the optional dereferencing of function pointer to the function itself, right?

PySpam_System_RETURN (*)PySpam_System_PROTO
expands to:
int (*)(const char *command)
This is a function pointer type. So basically the following:
(*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])
which translates to:
(*(int (*)(const char *command)) PySpam_API[0])
is calling the value of PySpam_API[0] as if it's a function with a const char* argument and an int return value (cast to function pointer). Note that this is still missing the arguments, so whoever uses the macro should give it arguments, such as:
PySpam_System("some string");
On your update:
The argument name is optional. They could have just written const char *. I believe the name was written for clarity. Right now, without looking anywhere else, I understood that the function takes a command, so it was helpful I'd say.
Again, you are right. The initial * dereferences the function pointer. In C, that's quite optional. It would be more symmetrical to put it, since you are dereferencing a pointer, but since not dereferencing a function pointer doesn't make sense, if you don't dereference it wouldn't make any difference, C would do the only sane thing for you. In fact, even if you put ****** instead of just one, it would still work.

Expand PySpam_System with the preprocessor, and you'd see:
(*(int (*)(const char *command)) PySpam_API[0])
The expression is (more or less) a cast to a 'pointer to function returning int and taking one argument of type const char *'. It would have to be followed by ("something") to convert the whole into a function call via the pointer to function. Thus, in the code, you might see:
PySpam_System("abc");
and the compiler would see:
(*(int (*)(const char *command)) PySpam_API[0])("abc");
and that is a call to the function stored in the array PySpam_API at index location 0. Obviously, the argument would probably not be a simple string literal, but a simple string literal is a representative const char *.
Question updates
Why const char *command, not just const char *. I thought that the name of the argument should be omitted in function pointer type declaration and type conversion? So it must not be omitted, but rather just can be?
Names for the arguments (such as command in the example) are optional in prototype declarations. There is also no rule stating that the name in the prototype declaration must match the name in the function definition. Sadly, C has not yet adopted the C++ convention that names are optional in the function definition if you are writing a function to conform to an interface but the particular implementation of the function does not need the argument. That is, in C++, you could write:
typedef int (*interface)(const char *cmd, int arg1, int arg2);
static int implementation(const char *cmd, int arg1, int) // C++, not C
{
return some_other_function(cmd, arg1, 23, 19);
}
The function implementation conforms to the interface type, but doesn't use the arg2 argument, but the compiler won't complain about the unused argument. C does not allow that convenience, so you get told about 'unused argument' even though you know perfectly well that it is unused. I believe there are compiler-specific ways around this particular problem.
Why (*(int (*)(const char *command)), not just (int (*)(const char *command)? What's the purpose of the outer (*[everything else here])? It's the optional dereferencing of function pointer to the function itself, right?
Right.
Note that there are two ways to invoke a function via a pointer to function, roughly the 'old' and the 'new' (where new means 'introduced and blessed by the C89 standard', so it is not exactly 'new').
The old notation required (give or take the prototypes which weren't available at the time):
#include <math.h>
double (*func)(double) = sin;
double x = (*func)(1.0);
with the parentheses and * around the function pointer. The idea is that if you have a pointer to a function, you need to dereference it to invoke the function. The more modern notation notes that the name of a function becomes a pointer to function (for example in the assignment), so you don't really need the (*func) notation. Hence the newer style is:
#include <math.h>
double (*func)(double) = sin;
double x = func(1.0);
Since I learned C when the old style was obligatory, I still prefer the slightly more verbose but completely unambiguous notation. The code in the PySpam_System macro uses the older notation too.
You can also play various silly games with function pointers, adding extra * and using a &, all of which are unnecessary.
double (*funca)(double) = &sin;
double (*func0)(double) = sin;
double (*func1)(double) = *sin;
double (*func2)(double) = **sin;
double (*func3)(double) = ***sin;
Only the func0 declaration is sensible; the rest are obfuscatory C.

Related

Return function in C [duplicate]

Normally, when declaring some variable, you put its type before it, like:
int a;
a function pointer may have type like: int(*)(int,int), in case we point to a function that takes two integers and returns an integer. But, when declaring such a pointer, its identifier is not after the type, like:
int(*)(int,int) mypointer;
instead, you must write the identifier in the middle:
int(*mypointer)(int,int);
why is this so?
I explain this in my answer to Why was the C syntax for arrays, pointers, and functions designed this way?, and it basically comes down to:
the language authors preferred to make the syntax variable-centric rather than type-centric. That is, they wanted a programmer to look at the declaration and think "if I write the expression *func(arg), that'll result in an int; if I write *arg[N] I'll have a float" rather than "func must be a pointer to a function taking this and returning that".
The C entry on Wikipedia claims that:
Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".
...citing p122 of K&R2.
This structure reflects how a normal function is declared (and used).
Consider a normal function definition:
int foo (int bar, int baz, int quux);
Now consider defining a function pointer to a function of the same signature:
int (*foo) (int, int, int);
Notice how the two structures mirror each other? That makes *foo much easier to identify as a function pointer rather than as something else.
If you're dealing with a function (not a pointer to one), the name is in the middle too. It goes like: return-type function-name "(" argument-list ")" .... For example, in int foo(int), int is the return type, foo the name and int the argument list.
A pointer to a function works pretty much the same way -- return type, then name, then argument list. In this case, we have to add a * to make it a pointer, and (since the * for a pointer is prefix) a pair of parentheses to bind the * to the name instead of the return type. For example, int *foo(int) would mean a function named foo that takes an int parameter and returns a pointer to an int. To get the * bound to foo instead, we need parentheses, giving int (*foo)(int).
This gets particularly ugly when you need an array of pointers to functions. In such a case, most people find it easiest to use a typedef for the pointer type, then create an array of that type:
typedef int (*fptr)(int);
fptr array[10];
I had seen at some places function pointers declared as
int (*foo) (int a, int b);
and at some places a and b are not mentioned and both still works.
so
int (*foo) (int, int)
is also correct.
A very simple way that I found to remember is as mentioned below:
Suppose function is declared as:
int function (int a , int b);
Step1: Simply put function in parentheses:
int (function) (int a , int b);
Step2: Place a * in front of function name and change the name:
int (*funcPntr) (int a , int b);
PS: I am not following proper coding guidelines for naming convention etc. in this answer.

In C, does * also mean the same thing as void when used as a function argument?

For example, look at the following (abstract) declaration :
int (*) (*)
// pointer to a function returning an int and taking no arguments
(which I got from the following site : http://www.vineetgupta.com/blog/deciphering-complex-c-declarations)
I thought that only void means no arguments. Does this really mean the same thing as :
int (*) (void)
If so, where does it state that * can be used to specify no arguments?
Also, am I correct in assuming that abstract declarations such as this only exist for type casting? If so then it must be invalid in its current form since it lacks the surrounding parenthesis right? So int(*)(void) is invalid, but (int(*)(void)) is valid, no?
pointer to a function returning an int and taking no arguments
That's not right - the function takes a pointer as its argument, but since the type specifier is missing, the base type of the pointer is assumed to be int. This is ancient (pre-standard) behavior, some compilers allow it, others don't.
I thought that only void means no arguments. Does this really mean the same thing as :
int (*) (void)
No, it doesn't, for the reason explained above.
Also, am I correct in assuming that abstract declarations such as this only exist for type casting?
No, they can be used in function argument lists in a function declaration too. So,
int factorial(int);
is perfectly fine, so is
void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
EDIT
int (*) (*)
results in an error when i tried in visual studio and its not the way of declaring.
If you want a function pointer to return an integer data with pointer as argument the correct way of doing it is below.
int(*foo)(datatype *).
where data type can be
int ,float,char etc
and void and * are not the same .

Declaring a pointer to const or a const pointer to const as a formal parameter

I was recently making some adjustments to code wherein I had to change a formal parameter in a function. Originally, the parameter was similar to the following (note, the structure was typedef'd earlier):
static MySpecialStructure my_special_structure;
static unsigned char char_being_passed; // Passed to function elsewhere.
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere.
int myFunction (MySpecialStructure * p_structure, unsigned char useful_char)
{
...
}
The change was made because I could define and initialize my_special_structure before compile time and myFunction never changed the value of it. This led to the following change:
static const MySpecialStructure my_special_structure;
static unsigned char char_being_passed; // Passed to function elsewhere.
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere.
int myFunction (const MySpecialStructure * p_structure, unsigned char useful_char)
{
...
}
I also noticed that when I ran Lint on my program that there were several Info 818's referencing a number of different functions. The info stated that "Pointer parameter 'x' (line 253) could be declared as pointing to const".
Now, I have two questions in regards to the above. First, in regards to the above code, since neither the pointer nor the variables within MySpecialStructure is changed within the function, is it beneficial to declare the pointer as constant as well? e.g. -
int myFunction (const MySpecialStructure * const p_structure, unsigned char useful_char)
My second question is in regards to the Lint information. Are there any benefits or drawbacks to declaring pointers as a constant formal parameter if the function is not changing its value... even if what you are passing to the function is never declared as a constant? e.g. -
static unsigned char my_char;
static unsigned char * p_my_char;
p_my_char = &my_char;
int myFunction (const unsigned char * p_char)
{
...
}
Thanks for your help!
Edited for clarification -
What are the advantages of declaring a pointer to const or a const pointer to const- as a formal parameter? I know that I can do it, but why would I want to... particularly in the case where the pointer being passed and the data it is pointing to are not declared constant?
What are the advantages of declaring a pointer as a const - as a formal parameter? I know that I can do it, but why would I want to... particularly in the case where the pointer being passed and the data it is pointing to are not declared constant?
I assumed you meant a pointer to const.
By have a pointer to const as a parameter, the advantage is you document the API by telling the programmer your function does not modify the object pointed by the pointer.
For example look at memcpy prototype:
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
It tells the programmer the object pointed to by s2 will not be modified through memcpy call.
It also provides compiler enforced documentation as the implementation will issue a diagnostic if you modify a pointee from a pointer to const.
const also allows to indicate users of your function that you won't modify this parameter behind their back
If you declare a formal parameter as const, the compiler can check that your code does not attempt to modify that parameter, yielding better software quality.
Const correctness is a wonderful thing. For one, it lets the compiler help keep you from making mistakes. An obvious simple case is assigning when you meant to compare. In that instance, if the pointer is const, the compiler will give you an error. Google 'const correctness' and you'll find many resources on the benefits of it.
For your first question, if you are damn sure of not modifying either the pointer or the variable it points to, you can by all means go ahead and make both of them constant!
Now, for your Qn as to why declare a formal pointer parameter as const even though the passed pointer is not constant, A typical use case is library function printf(). printf is supposed to accept const char * but the compiler doesn't complain even if you pass a char* to it. In such a case, it makes sense that printf() doesn't not build upon the user's mistake and alter user's data inadvertantly! Its like printf() clearly telling- Whether you pass a const char * or char*, dont worry, I still wont modify your data!
For your second question, const pointers find excellent application in the embedded world where we generally write to a memory address directly. Here is the detailed explanation
Well, what are the advantages of declaring anything as a const while you have the option to not to do so? After all, if you don't touch it, it doesn't matter if it's const or not. This provides some safety checks that the compiler can do for you, and it gives some information of the function interface. For example, you can safely pass a string literal to a function that expects a const char *, but you need to be careful if the parameter is declared as just a char *.

How do I quiet the C compiler about a function pointer takes any number of arguments?

I have a function pointer inside a struct that gets dynamically set at runtime to the address of another function in various places in my code. It is defined in my header file like this:
void *(*run)();
During compile time, I get the following warning about this:
warning: function declaration isn't a prototype
This warning is benign, because the pointer is used in many places in my code to call the function it points to, and everything works just fine. However, I would really like to silence the warning.
If I change it to this:
void *(*run)(void);
I get compile errors whever I use it, because the various functions that make use of the pointer have different numbers of arguments, and saying void inside the parenthesies tells the compiler it accepts no arguments.
I can't use a va_list or anything fancy like that, as this is simply a pointer to another function, and I use a single pointer for them all because it keeps the code clean and simple.
I can silence the warning with adding this to my compiler flags:
-Wno-strict-prototypes
But I'd rather not have to disable compiler warnings with flags if I can avoid it.
So my question is: How do I notate this function pointer in the code in such a way that the compiler is satisfied with the fact that it accepts any number of any kind of arguments?
The code works perfectly. I just want the warning to go away.
Store the pointer as a void * and cast to the appropriate function pointer type when necessary? Keep in mind that it isn't necessarily safe to call one type of function pointer as if it were another type, so the warning you're starting out with isn't entirely invalid.
You can cast a function pointer like so:
void *genericPointer = ...;
void (*fp)(int, int) = genericPointer;
fp(123, 456);
Note that:
There's no explicit casting necessary here, as void * can always be cast to any pointer type.
The initial "void" before (*fp) is the return type of the function pointer.
You are trying to do things clean - i.e. involve the compiler in checks, but the design you invented simply cannot be clean by its principle. You cannot involve compiler in prototype checks this way, because you always must know, which parameters to pass at this particular case in runtime. Compiler cannot check this and if you make a mistake, segmentation fault is on the way.
But if I remember well, something like this was maybe used also in linux kernel (?). The solution is to have a general pointer (like the one you have) and each time you call a particular function you just typecast it to the pointer to function with the particular arguments. You may need to typecast it to void * first to silence the compiler again :-)
In C, when you call a function without a prototype visible, default argument promotions are applied to all of the arguments that you pass to the function. This means that the types that you actually pass do not necessarily match the types received by the function.
E.g.
void (*g)();
void f()
{
float x = 0.5;
g(x); // double passed
}
This means that you need to know that the function that you are actually calling has a compatible signature to that implied by the arguments that you are passing after promotion.
Given that you need to know this in any case you must know the function signature of the actual function being called at the call site which is using the function pointer. With this knowledge it is usually simpler and cleaner to use a function pointer with the correct prototype and you can avoid default argument promotion entirely.
Note that as you are defining your functions with prototypes, when you assigned a pointer to your function to a function pointer without a prototype you effective converted, say, a void(*)(int, int) to a void(*)() so it is completely correct and desirable to perform the reverse conversion before calling the function. gcc allows both these conversions without emitting any warnings.
E.g.
void PerformCall( void(*p)() )
{
if (some_condition)
{
// due to extra knowledge I now know p takes two int arguments
// so use a function pointer with the correct prototype.
void(*prototyped_p)(int, int) = p;
prototyped_p( 3, 4 );
}
}
Try typedefing the function pointer declaration and then have the caller explicityly cast it:
typedef void *(*run)();
//when calling...
void my_foo() {}
run r = (run)my_foo;
If the different function signatures are known, use a union. Otherwise, use a pointer of type void (*)(void) (actually, any function pointer type would do) to hold the generic pointer and convert to the proper type when setting the value and calling the code.
Example using a union:
union run_fn
{
void *(*as_unary)(int);
void *(*as_binary)(int, int);
};
struct foo
{
union run_fn run;
};
void *bar(int, int);
struct foo foo;
foo.run.as_binary = bar;
void *baz = foo.run.as_binary(42, -1);
Example using explicit casts:
struct foo
{
void (*run)(void);
};
void *bar(int, int);
struct foo foo;
foo.run = (void *(*)(int, int))bar;
void *baz = ((void *(*)(int, int))foo.run)(42, -1);
Don't use a void * to hold function pointers - such a conversion is unspecified by the ISO C standard and may be unavailable on certain architectures.
Ignoring the warning and using your code as-is is actually also a possibility, but keep in mind that any function argument will be subject to the default argument promotions and it's your responsibility that the promoted arguments properly match the declared parameters.

A Question About Function Pointer In C

There's the following declarations:
void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);
int strcmp(char *s, char *t);
Then, somewhere in the program there is the following call:
qsort((void**) lineptr, 0, nlines-1,
(int (*)(void*,void*))(numeric ? numcmp : strcmp));
(Ignore the first three arguments and numeric).
I ask what is this:
(int (*)(void*,void*))(numeric ? numcmp : strcmp)
I understand that qsort is expecting a "pointer to function that gets two void pointers and returns an int" as it's 4th argument but how what's written above satisfies that?
It seems to me like some sort of cast because it is made of two parentheses, but that would be a very odd cast. Because it takes a function and makes this function a "pointer to function that gets two void pointers and returns an int". Which is meaningless.
(I followed here the rule that a type type in parenthesis before a variable promotes the variable to that type).
So I think I just get it wrong, maybe someone can tell me how to read this, what's the order?
What's happening here is indeed a cast. Lets ignore the ternary for a second and pretend that numcmp is always used. For the purpose of this question, functions can act as function pointers in C. So if you look at the type of numeric it is actually
(int (*)(int*,int*))
In order for this to be properly used in qsort it needs to have void parameters. Because the types here all have the same size with respect to parameters and return types, it's possible to substitute on for the other. All that's needed is a cast to make the compiler happy.
(int (*)(void*,void*))(numcmp )
You've missed the trick here - the portion
(numeric ? numcmp : strcmp)
is using the ternary operator to choose which function is being called inside of qsort. If the data is numeric, it uses numcmp. If not, it uses strcmp. A more readable implementation would look like this:
int (*comparison_function)(void*,void*) =
(int (*)(void*,void*))(numeric ? numcmp : strcmp);
qsort((void**) lineptr, 0, nlines-1, comparison_function);
As others have pointed out, for
(int (*)(void*,void*))(numeric ? numcmp : strcmp)
then the following is a type cast
(int (*)(void*,void*))
and the expression is
(numeric ? numcmp : strcmp)
C declarations can be quite difficult to read, but it is possible to learn. The method is to start at the inner part and then go right one step, then left one step, continuing right, left, right, left, etc outwards until finished. You do not cross outside a parenthesis before everything inside has been evaluated. For instance for the type cast above, (*) indicates this is a pointer. Pointer was the only thing inside the parenthesis so then we evaluate to the right side outside it. (void*,void*) indicates that is a pointer to a function with two pointer arguments. Finally int indicates the return type of the function. The outer parenthesis makes this a type cast.
Update: two more detailed articles: The Clockwise/Spiral Rule and Reading C Declarations: A Guide for the Mystified.
However, the good news is that although the above is extremely useful to know, there is an extremely simple way to cheat: the cdecl program can convert from C to English description and vice versa:
cdecl> explain (int (*)(void*,void*))
cast unknown_name into pointer to function (pointer to void, pointer to void) returning int
cdecl> declare my_var as array 5 of pointer to int
int *my_var[5]
cdecl>
Exercise: What kind of variable is i?
int *(*(*i)[])(int *)
Answer in rot13 in case you do not have cdecl installed on your machine (but you really should!):
pqrpy> rkcynva vag *(*(*v)[])(vag *)
qrpyner v nf cbvagre gb neenl bs cbvagre gb shapgvba (cbvagre gb vag) ergheavat cbvagre gb vag
pqrpy>
You can do it without the function pointer cast. Here's how. In my experience, in most places, if you are using a cast, you are doing it wrong.
Note that the standard definition of qsort() includes const:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Note that the string comparator is given two 'char **' values, not 'char *' values.
I write my comparators so that casts are unnecessary in the calling code:
#include <stdlib.h> /* qsort() */
#include <string.h> /* strcmp() */
int num_cmp(const void *v1, const void *v2)
{
int i1 = *(const int *)v1;
int i2 = *(const int *)v2;
if (i1 < i2)
return -1;
else if (i1 > i2)
return +1;
else
return 0;
}
int str_cmp(const void *v1, const void *v2)
{
const char *s1 = *(const char **)v1;
const char *s2 = *(const char **)v2;
return(strcmp(s1, s2));
}
Forcing people to write casts in the code using your functions is ugly. Don't.
The two functions I wrote match the function prototype required by the standard qsort(). The name of a function when not followed by parentheses is equivalent to a pointer to the function.
You will find in older code, or code written by those who were brought up on older compilers, that pointers to functions are used using the notation:
result = (*pointer_to_function)(arg1, arg2, ...);
In modern style, that is written:
result = pointer_to_function(arg1, arg2, ...);
Personally, I find the explicit dereference clearer, but not everyone agrees.
Whoever wrote that code snippet was trying to be too clever. In his mind, he probably thinks he is being a good programmer by making a clever "one-liner". In reality, he is making code that is less readable and is obnoxious to work with over the long term and should be rewritten in a more obvious form similar to Harper Shelby's code.
Remember the adage from Brian Kernighan:
Debugging is twice as hard as writing
the code in the first place.
Therefore, if you write the code as
cleverly as possible, you are, by
definition, not smart enough to debug
it.
I do lots of performance critical coding with hard real time deadlines... and I have still not seen a place where a dense one-liner is appropriate.
I have even messed around with compiling and checking the asm to see if the one-liner has a better compiled asm implementation but have never found the one-liner to be worth it.
I would probably read it like this:
typedef int (*PFNCMP)(void *, void *);
PFNCMP comparison_function;
if (numeric)
{
comparison_function = numcmp;
}
else
{
comparison_function = strcmp;
}
qsort((void**) lineptr, 0, nlines-1, comparison_function);
The example in the question has an explicit case.
Your logic is correct i think. It is indeed casting to "pointer to function that gets two void pointers and returns an int" which is the required type by the method signature.
Both numcmp and strcmp are pointers to functions which take two char* as parameters and returns an int. The qsort routine expects a pointer to a function that takes two void* as parameters and returns an int. Hence the cast. This is safe, since void* acts as a generic pointer. Now, on to reading the declaration: Let's take your strcmp's declaration:
int strcmp(char *, char *);
The compiler reads it as strcmp is actually:
int (strcmp)(char *, char *)
a function (decaying to a pointer to a function in most cases) which takes two char * arguments. The type of the pointer strcmp is therefore:
int (*)(char *, char *)
Hence, when you need to cast another function to be compatible to strcmp you'd use the above as the type to cast to.
Similarly, since qsort's comparator argument takes two void *s and thus the odd cast!

Resources