Is this valid C99 code? (I guess I'm asking whether it's portable)
void test(void){
return;
}
void (*fp)(void) = test;
if (fp == test){ <--- This line
printf("Success\n");
}
I gather only pointers of the same type can be compared with one another, so maybe my question is whether function names like 'test' are just pointer aliases? Or maybe someone can tell me what my question is better than I can :)
The code is valid ANSI C.
Actually what happens is, a function name such as test in your code, is automatically converted to a pointer to function.
You could change test to &test, the result is the same.
Yes, it is fine. The C standard is pretty self-explanatory in this case (C11 6.3.2.1/4):
A function designator is an expression that has function type. Except when it is the
operand of the sizeof operator, or the unary & operator, a function designator with
type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
In your case test is an expression with function type. It gets converted to a function pointer of void(*)(void) type. This is a compatible pointer type with fp, so the == operator allows it.
Regarding the equality operator ==, the standard says (C11 6.5.9, emphasis mine):
Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function,
Related
Why and how does dereferencing a function pointer just "do nothing"?
This is what I am talking about:
#include<stdio.h>
void hello() { printf("hello"); }
int main(void) {
(*****hello)();
}
From a comment over here:
function pointers dereference just
fine, but the resulting function
designator will be immediately
converted back to a function pointer
And from an answer here:
Dereferencing (in way you think) a
function's pointer means: accessing a
CODE memory as it would be a DATA
memory.
Function pointer isn't suppose to be
dereferenced in that way. Instead, it
is called.
I would use a name "dereference" side
by side with "call". It's OK.
Anyway: C is designed in such a way
that both function name identifier as
well as variable holding function's
pointer mean the same: address to CODE
memory. And it allows to jump to that
memory by using call () syntax either
on an identifier or variable.
How exactly does dereferencing of a function pointer work?
It's not quite the right question. For C, at least, the right question is
What happens to a function value in an rvalue context?
(An rvalue context is anywhere a name or other reference appears where it should be used as a value, rather than a location — basically anywhere except on the left-hand side of an assignment. The name itself comes from the right-hand side of an assignment.)
OK, so what happens to a function value in an rvalue context? It is immediately and implicitly converted to a pointer to the original function value. If you dereference that pointer with *, you get the same function value back again, which is immediately and implicitly converted into a pointer. And you can do this as many times as you like.
Two similar experiments you can try:
What happens if you dereference a function pointer in an lvalue context—the left-hand side of an assignment. (The answer will be about what you expect, if you keep in mind that functions are immutable.)
An array value is also converted to a pointer in an lvalue context, but it is converted to a pointer to the element type, not to a pointer to the array. Dereferencing it will therefore give you an element, not an array, and the madness you show doesn't occur.
Hope this helps.
P.S. As to why a function value is implicitly converted to a pointer, the answer is that for those of us who use function pointers, it's a great convenience not to have to use &'s everywhere. There's a dual convenience as well: a function pointer in call position is automatically converted to a function value, so you don't have to write * to call through a function pointer.
P.P.S. Unlike C functions, C++ functions can be overloaded, and I'm not qualified to comment on how the semantics works in C++.
C++03 §4.3/1:
An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function.
If you attempt an invalid operation on a function reference, such as the unary * operator, the first thing the language tries is a standard conversion. It's just like converting an int when adding it to a float. Using * on a function reference causes the language to take its pointer instead, which in your example, is square 1.
Another case where this applies is when assigning a function pointer.
void f() {
void (*recurse)() = f; // "f" is a reference; implicitly convert to ptr.
recurse(); // call operator is defined for pointers
}
Note that this doesn't work the other way.
void f() {
void (&recurse)() = &f; // "&f" is a pointer; ERROR can't convert to ref.
recurse(); // OK - call operator is *separately* defined for references
}
Function reference variables are nice because they (in theory, I've never tested) hint to the compiler that an indirect branch may be unnecessary, if initialized in an enclosing scope.
In C99, dereferencing a function pointer yields a function designator. §6.3.2.1/4:
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
This is more like Norman's answer, but notably C99 has no concept of rvalues.
It happens with a few implicit conversions. Indeed, per the C standard:
ISO/IEC 2011, section 6.3.2.1 Lvalues, arrays, and function designators, paragraph 4
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type “function returning type” is converted to an expression that has type “pointer to function returning type”.
Consider the following code:
void func(void);
int main(void)
{
void (*ptr)(void) = func;
return 0;
}
Here, the function designator func has the type “function returning void” but is immediately converted to an expression that has type “pointer to function returning void”. However, if you write
void (*ptr)(void) = &func;
then the function designator func has the type “function returning void” but the unary & operator explicitly take the address of that function, eventually yielding the type “pointer to function returning void”.
This is mentioned in the C standard:
ISO/IEC 2011, section 6.5.3.2 Address and indirection operators, paragraph 3
The unary & operator yields the address of its operand. If the operand has type “type”, the result has type “pointer to type”.
In particular, dereferencing a function pointer is redundant. Per the C standard:
ISO/IEC 2011, section 6.5.2.2 Function calls, paragraph 1
The expression that denotes the called function shall have type “pointer to function returning void” or returning a complete object type other than an array type. Most often, this is the result of converting an identifier that is a function designator.
ISO/IEC 2011, section 6.5.3.2 Address and indirection operators, paragraph 4
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator.
So when you write
ptr();
the function call is evaluated with no implicit conversion because ptr is already a pointer to function. If you explicitly dereference it with
(*ptr)();
then the dereferencing yields the type “function returning void” which is immediately converted back to the type “pointer to function returning void” and the function call occurs. When writing an expression composed of x unary * indirection operators such as
(****ptr)();
then you just repeat the implicit conversions x times.
It does make sense that calling functions involves function pointers. Before executing a function, a program pushes all of the parameters for the function onto the stack in the reverse order that they are documented. Then the program issues a call instruction indicating which function it wishes to start. The call instruction does two things:
First it pushes the address of the next instruction, which is the return address, onto the stack.
Then, it modifies the instruction pointer %eip to point to the start of the function.
Since calling a function does involve modifying an instruction pointer, which is a memory address, it makes sense that the compiler implicitly converts a function designator to a pointer to function.
Even though it may seems unrigorous to have these implicit conversions, it can be useful in C (unlike C++ which have namespaces)
to take advantage of the namespace defined by a struct identifier to encapsulate variables.
Consider the following code:
void create_person(void);
void update_person(void);
void delete_person(void);
struct Person {
void (*create)(void);
void (*update)(void);
void (*delete)(void);
};
static struct Person person = {
.create = &create_person,
.update = &update_person,
.delete = &delete_person,
};
int main(void)
{
person.create();
person.update();
person.delete();
return 0;
}
It is possible to hide the implementation of the library in other translation units and to choose to only expose the struct encapsulating the pointers to functions, to use them in place of the actual function designators.
Put yourself in the shoes of the compiler writer. A function pointer has a well defined meaning, it is a pointer to a blob of bytes that represent machine code.
What do you do when the programmer dereferences a function pointer? Do you take the first (or 8) bytes of the machine code and reinterpret that as a pointer? Odds are about 2 billion to one that this won't work. Do you declare UB? Plenty of that going around already. Or do you just ignore the attempt? You know the answer.
How exactly does dereferencing of a function pointer work?
Two steps. The first step is at compile time, the second at runtime.
In step one, the compiler sees it has a pointer and a context in which that pointer is dereferenced (such as (*pFoo)() ) so it generates code for that situation, code that will be used in step 2.
In step 2, at runtime the code is executed. The pointer contains some bytes indicating which function should be executed next. These bytes are somehow loaded into the CPU. A common case is a CPU with an explicit CALL [register] instruction. On such systems, a function pointer can be simply the address of a function in memory, and the derefencing code does nothing more than loading that address into a register followed by a CALL [register] instruction.
Why and how does dereferencing a function pointer just "do nothing"?
This is what I am talking about:
#include<stdio.h>
void hello() { printf("hello"); }
int main(void) {
(*****hello)();
}
From a comment over here:
function pointers dereference just
fine, but the resulting function
designator will be immediately
converted back to a function pointer
And from an answer here:
Dereferencing (in way you think) a
function's pointer means: accessing a
CODE memory as it would be a DATA
memory.
Function pointer isn't suppose to be
dereferenced in that way. Instead, it
is called.
I would use a name "dereference" side
by side with "call". It's OK.
Anyway: C is designed in such a way
that both function name identifier as
well as variable holding function's
pointer mean the same: address to CODE
memory. And it allows to jump to that
memory by using call () syntax either
on an identifier or variable.
How exactly does dereferencing of a function pointer work?
It's not quite the right question. For C, at least, the right question is
What happens to a function value in an rvalue context?
(An rvalue context is anywhere a name or other reference appears where it should be used as a value, rather than a location — basically anywhere except on the left-hand side of an assignment. The name itself comes from the right-hand side of an assignment.)
OK, so what happens to a function value in an rvalue context? It is immediately and implicitly converted to a pointer to the original function value. If you dereference that pointer with *, you get the same function value back again, which is immediately and implicitly converted into a pointer. And you can do this as many times as you like.
Two similar experiments you can try:
What happens if you dereference a function pointer in an lvalue context—the left-hand side of an assignment. (The answer will be about what you expect, if you keep in mind that functions are immutable.)
An array value is also converted to a pointer in an lvalue context, but it is converted to a pointer to the element type, not to a pointer to the array. Dereferencing it will therefore give you an element, not an array, and the madness you show doesn't occur.
Hope this helps.
P.S. As to why a function value is implicitly converted to a pointer, the answer is that for those of us who use function pointers, it's a great convenience not to have to use &'s everywhere. There's a dual convenience as well: a function pointer in call position is automatically converted to a function value, so you don't have to write * to call through a function pointer.
P.P.S. Unlike C functions, C++ functions can be overloaded, and I'm not qualified to comment on how the semantics works in C++.
C++03 §4.3/1:
An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function.
If you attempt an invalid operation on a function reference, such as the unary * operator, the first thing the language tries is a standard conversion. It's just like converting an int when adding it to a float. Using * on a function reference causes the language to take its pointer instead, which in your example, is square 1.
Another case where this applies is when assigning a function pointer.
void f() {
void (*recurse)() = f; // "f" is a reference; implicitly convert to ptr.
recurse(); // call operator is defined for pointers
}
Note that this doesn't work the other way.
void f() {
void (&recurse)() = &f; // "&f" is a pointer; ERROR can't convert to ref.
recurse(); // OK - call operator is *separately* defined for references
}
Function reference variables are nice because they (in theory, I've never tested) hint to the compiler that an indirect branch may be unnecessary, if initialized in an enclosing scope.
In C99, dereferencing a function pointer yields a function designator. §6.3.2.1/4:
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
This is more like Norman's answer, but notably C99 has no concept of rvalues.
It happens with a few implicit conversions. Indeed, per the C standard:
ISO/IEC 2011, section 6.3.2.1 Lvalues, arrays, and function designators, paragraph 4
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type “function returning type” is converted to an expression that has type “pointer to function returning type”.
Consider the following code:
void func(void);
int main(void)
{
void (*ptr)(void) = func;
return 0;
}
Here, the function designator func has the type “function returning void” but is immediately converted to an expression that has type “pointer to function returning void”. However, if you write
void (*ptr)(void) = &func;
then the function designator func has the type “function returning void” but the unary & operator explicitly take the address of that function, eventually yielding the type “pointer to function returning void”.
This is mentioned in the C standard:
ISO/IEC 2011, section 6.5.3.2 Address and indirection operators, paragraph 3
The unary & operator yields the address of its operand. If the operand has type “type”, the result has type “pointer to type”.
In particular, dereferencing a function pointer is redundant. Per the C standard:
ISO/IEC 2011, section 6.5.2.2 Function calls, paragraph 1
The expression that denotes the called function shall have type “pointer to function returning void” or returning a complete object type other than an array type. Most often, this is the result of converting an identifier that is a function designator.
ISO/IEC 2011, section 6.5.3.2 Address and indirection operators, paragraph 4
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator.
So when you write
ptr();
the function call is evaluated with no implicit conversion because ptr is already a pointer to function. If you explicitly dereference it with
(*ptr)();
then the dereferencing yields the type “function returning void” which is immediately converted back to the type “pointer to function returning void” and the function call occurs. When writing an expression composed of x unary * indirection operators such as
(****ptr)();
then you just repeat the implicit conversions x times.
It does make sense that calling functions involves function pointers. Before executing a function, a program pushes all of the parameters for the function onto the stack in the reverse order that they are documented. Then the program issues a call instruction indicating which function it wishes to start. The call instruction does two things:
First it pushes the address of the next instruction, which is the return address, onto the stack.
Then, it modifies the instruction pointer %eip to point to the start of the function.
Since calling a function does involve modifying an instruction pointer, which is a memory address, it makes sense that the compiler implicitly converts a function designator to a pointer to function.
Even though it may seems unrigorous to have these implicit conversions, it can be useful in C (unlike C++ which have namespaces)
to take advantage of the namespace defined by a struct identifier to encapsulate variables.
Consider the following code:
void create_person(void);
void update_person(void);
void delete_person(void);
struct Person {
void (*create)(void);
void (*update)(void);
void (*delete)(void);
};
static struct Person person = {
.create = &create_person,
.update = &update_person,
.delete = &delete_person,
};
int main(void)
{
person.create();
person.update();
person.delete();
return 0;
}
It is possible to hide the implementation of the library in other translation units and to choose to only expose the struct encapsulating the pointers to functions, to use them in place of the actual function designators.
Put yourself in the shoes of the compiler writer. A function pointer has a well defined meaning, it is a pointer to a blob of bytes that represent machine code.
What do you do when the programmer dereferences a function pointer? Do you take the first (or 8) bytes of the machine code and reinterpret that as a pointer? Odds are about 2 billion to one that this won't work. Do you declare UB? Plenty of that going around already. Or do you just ignore the attempt? You know the answer.
How exactly does dereferencing of a function pointer work?
Two steps. The first step is at compile time, the second at runtime.
In step one, the compiler sees it has a pointer and a context in which that pointer is dereferenced (such as (*pFoo)() ) so it generates code for that situation, code that will be used in step 2.
In step 2, at runtime the code is executed. The pointer contains some bytes indicating which function should be executed next. These bytes are somehow loaded into the CPU. A common case is a CPU with an explicit CALL [register] instruction. On such systems, a function pointer can be simply the address of a function in memory, and the derefencing code does nothing more than loading that address into a register followed by a CALL [register] instruction.
I'm relatively new to C, and found it intriguing that both of the following calls to the function pointer compile and work fine. One with and one without dereferencing the function pointer before calling it.
#include <stdio.h>
#include <stdlib.h>
void func() {
puts("I'm a func");
}
int main(void) {
void (*f)() = func;
f();
(*f)();
return EXIT_SUCCESS;
}
I think I understand that (*f)() is the "official" way to call a function pointer, but why does simply calling f() work? Is that syntactic sugar of recent C versions?
This is a piece of syntactic/semantic sugar that has, AFAIK, worked since the very earliest versions of C. It makes sense if you think of functions as pointers to code.
The only special rule needed to make function pointers work this way is that indirecting a function pointer gives the same pointer back (because you can't manipulate code in standard C anyway): when f is a function pointer, then f == (*f) == (**f), etc.
(Aside: watch out with declaration such as void (*f)(). An empty argument list denotes an old-style, pre-C89 function declaration that matches on the return type only. Prefer void (*f)(void) for type safety.)
A function call expression is always of the form "function pointer", "round parenthesis", "arguments", "round parenthesis". In order for you not to have to spell out (&printf)("Hello World\n") every time1, there is a separate rule by which an expression which denotes a function decays to the respective function pointer.
Since a function pointer can be dereferenced to give an expression that denotes a function again, this will again decay, so you can keep dereferencing and there'll be a lot of decay:
(&f)(); // no decay (decay does not happen when the expression
// is the operand of &)
f(); // one decay
(*f)(); // two decays
(**f)(); // three decays
1) Early Perl has function syntax like that.
The C 2011 standard says in clause 6.3.2.1, paragraph 4:
Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
This means that, if f designates a function, then, in a call such as f(), f is automatically converted to &f, resulting in (&f)(). This is actually the “proper” way to call a function, because the function-call expression requires a pointer to a function.
Now consider what happens in *f. The f is automatically converted to &f, so we have *&f. In this expression, the result of the * operator is a function, f; it just reverse the operation performed by &. So *&f is the same as f. We can repeat this indefinitely: **f is automatically converted to **&f, which is *f, which is automatically converted to *&f, which is f, which is automatically converted to &f.
In C you can call your function like:
f();
(*f)();
(**f)();
(********f)();
(*****************************f)();
all are valid. In C, dereferencing or taking the address of a function just evaluates to a pointer to that function, and dereferencing a function pointer just evaluates back to the function pointer. C is designed in such a way that both function name identifier as well as variable holding function's pointer mean the same: address to CODE memory. And it allows to jump to that memory by using call () syntax either on an identifier or variable.
And the last but but least, standard says that:
C11: 6.3.2.1:
4 A function designator is an expression that has function type. Except when it is the
operand of the sizeof operator, the _Alignof operator,65) or the unary & operator, a
function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
function call with different semantics
I am reading about function pointers in C. I tried this program:
#include <stdio.h>
int foo(void)
{
printf("At foo.");
return 0;
}
int main (void)
{
printf("%p\t%p\t%p\n", &foo, foo, *foo);
return 0;
}
The output for this program is:
0040138C 0040138C 0040138C
In 1-D array <datatype> <identifier>[N], identifier and &identifier points to the same value but the nature of the values are different. One is of type datatype* and the other is of type pointer to the 1-D array. Analogously, for functions, the foo and &foo are the same. But what about *foo and what is the nature of &foo, foo, *foo?
A plain foo is already a function pointer:
6.3.2.1 - 4
A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator or the unary
& operator, a function designator with type ‘‘function returning
type’’ is converted to an expression that has type ‘‘pointer to
function returning type’’.
You may obtain the address of a function using &, which yields a pointer to function ...:
6.5.3.1 - 1-3
The operand of the unary & operator shall be either a function
designator... The unary & operator yields the address of its operand.
If the operand has type ‘‘type’’,
the result has type ‘‘pointer to type’’
It's legal to apply the indirection operator to a function designator:
6.5.3.2 - 3
The unary * operator denotes indirection. If the operand points to a
function, the result is a function designator
tldr:
So there you have it. They all do the same thing.
EDIT
What is 'function type` in C
Quick! To the standard!
6.2.5 - 1
Types are partitioned into object types (types that describe
objects) and function types (types that describe functions).
6.2.5 - 20
A function type describes a function with specified return type. A
function type is characterized by its return type and the
number and types of its parameters. A function type is said to be
derived from its return type, and if its return type is T, the
function type is sometimes called ‘‘function returning T’’. The
construction of a function type from a return type is called
‘‘function type derivation’’
In C/C++ a function can be used only in 2 ways: you can take its address and you can call it. You cannot do anything else with it.
So, foo is a function itself. C++ has a standard conversion 4.3 Function-to-pointer conversion. This means that foo will be automatically converted to &foo. Notation &&&&foo results in a syntax error.
In C++ 5.3.1.1 Unary operators there is wording that allows dereferencing function pointers with the result of the function itself. This implies that multiple *'s should not be allowed. Nevertheless they work at least in MSVC and GCC. Maybe this is so because compiler applies Function-to-pointer conversion immediately after dereferencing before processing the next operation.
I do not see good reasoning for allowing multiple *'s and not allowing multiple &'s with functions. For some reason different logic is implemented for * and & operations.
You can try to cast foo to char* and dereference this pointer. It will contain bytes of the machine code. The length of these bytes is unknown. Read/write protection of this address is unknown too. Many CPU architectures allow setting execute bit without setting read and write bits. So, you can call the function but an attempt to read at this address may result in a crash.
I found these work types of code:
hash_init.key = &hash_key_lc;
And
ls->handler = init_connection;
Here both hash_key_lc and init_connection are functions,but one is with & the other not,why?
UPDATE
so they are the same thing,but what's the rational??
This is identical to the following question:
In C, what is the difference between `&function` and `function` when passed as arguments?
The accepted answer there:
There is no difference. For evidence
see the C99 specification (section
6.7.5.3.8).
"A declaration of a parameter as
‘‘function returning type’’ shall be
adjusted to ‘‘pointer to function
returning type’’, as in 6.3.2.1."
reference/deference on a function is treated as a language special case in c,as function deserves this kind of special case ,it can't be passed by a certain value,you can only pass it by address/reference.
See C99 section 6.3.2.1, §4:
A function designator is an
expression that has function type.
Except when it is the operand of the
sizeof operator or the unary &
operator, a function designator with
type ‘‘function returning type’’ is
converted to an expression that has
type ‘‘pointer to function returning
type’’.
Thus, if foo is a function, the expressions foo and &foo are mostly interchangeable, in particular
foo == &foo
This is similar to how expressions with array type are implicitly converted to expressions with pointer type. Also, if fp is a function pointer, you can call it with or without dereferencing, ie the expressions
(*fp)(42)
and
fp(42)
are equivalent. Function calls are actually defined in terms of function pointers (section 6.5.2.2 §1) and not function designators, ie as far as language semantics go, *fp in the first example will implicitly converted back to fp before the parens are applied.