How come the addresses of main and &main are the same? [duplicate] - c

This question already has answers here:
How does dereferencing of a function pointer happen?
(5 answers)
Closed 2 years ago.
According to the GNU C manual, functions can be called using function pointers like so:
func (j); /* (*func) (j); would be equivalent. */
So my reasoning here is: func itself is a pointer to the func(int) function. When you call func(j), you are implicitly accessing the value of the pointer func (you are moving to the memory location where func is), in the same way as when you have a pointer to an integer, for example, and you access the value stored in that position of the memory using *. That would be consistent with the fact that you can call that same function using (*func)(j).
In fact, in cprogramming.com, they say you can have a pointer to a pointer of a function. So I am therefore guessing they work like any other kind of pointers.
But if that's the case, why is it that this code works?
#include <stdlib.h>
#include <stdio.h>
void a(int n) {
printf("%d\n", num);
}
int main() {
int x = 5;
void (*func)(int); // Declare a pointer to a function
func = &a; // Pointer to a pointer to a function
(*func)(x); // Calls the function (why?)
func = a; // Pointer to a function
(*func)(x); // Calls the function (makes sense)
}
Moreover, if you call:
printf("%s\n", (&a == a) ? "True" : "False");
It prints True!
I am sure that &foo is not the same as &&foo, for example, so why does it seem to be the case that func is the same as &func?

N1570 6.3.2.1 Lvalues, arrays, and function designators says:
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’’.
Here a and *func are function designators because they have function type. a in &a is not converted to a pointer because it is the operand of the unary & operator and the pointer to the function is retrieved by the & operator.
On the other hand, a in func = a; is converted to the pointer to the function according to this rule.
Therefore a and &a in this code are equivalent.
Also func in func(x); is converted to the pointer according to this rule.
(*func)(x); is:
func is converted to the pointer according to this rule
The pointer is dereferenced by * in *func
*func is converted to the pointer according to this rule
Thus (*func)(x); is equivalent to func(x);.

A function designator used in expressions is implicitly converted to pointer to the function.
So for example you could call your function like
( **********a )( 5 );
That is in this expression *a the function designator a is converted to pointer to the function. Applying the dereference operator * you again get a function designator that in turn is converted to pointer to the function in the expression **a. And so on.
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
4 A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator65) 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’’.
So in this assignment
func = &a; // Pointer to a pointer to a function
there is used the operator & (see the quote from the C Standard) that means that the function designator a is not converted to function pointer in this expression. And you do not have pointer to a function pointer as you wrote in the comment to the statement above.

From the very documentation you've provided:
5.6 Calling Functions Through Function Pointers
You can also call a function identified by a pointer. The indirection operator * is optional when doing this.
#include <stdio.h>
void foo (int i)
{
printf ("foo %d!\n", i);
}
void bar (int i)
{
printf ("%d bar!\n", i);
}
void message (void (*func)(int), int times)
{
int j;
for (j=0; j<times; ++j)
func (j); /* (*func) (j); would be equivalent. */
}
void example (int want_foo)
{
void (*pf)(int) = &bar; /* The & is optional. */
if (want_foo)
pf = foo;
message (pf, 5);
}
So, The indirection operator * is optional when doing this. and /* The & is optional. */ comments says it all. They're optional. Why they are optional is explained by #MikeCat and #Vlad from Moscow

Related

Referencing a function pointer with ampersand works fine while I prefer without but using & is an indicator of referencing an address

The code below shows the reference to function pointer:
typedef int (*t_somefunc)(int,int);
int product(int, int);
int main(void) {
t_somefunc afunc = &product; // "product" works fine without "&"
What do we use "&" for referencing function pointer?
See full working code:
#include <stdio.h>
typedef int (*t_somefunc)(int,int);
int product(int, int);
int main(void) {
t_somefunc afunc = &product; // product without & works also
int x2 = (*afunc)(123, 456); // call product() to calculate 123*456
printf("x2 value is %d\n", x2);
return 1;
}
int product(int u, int v) {
return u*v;
}
Functions are automatically converted to pointers for programmer convenience.
When a function is used in an expression, it is automatically converted to a pointer to the function, unless it is the operand of sizeof or unary &. C 2018 6.3.2.1 4 says:
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 fact, if you attempt to convert the pointer back to a function by applying *, the automatic conversion will happen again. You can write t_somefunc afunc = *******************product; and still end up with the address of product.)
In declarations of function parameters, a function will be automatically adjusted to be a pointer to a function. C 2018 6.7.6.3 8 says:
A declaration of a parameter as “function returning type” shall be adjusted to “pointer to function returning type”, as in 6.3.2.1.
(This is called an adjustment because there is no value being converted; the declaration is changed to declare a pointer to a function instead of a function.)
Nothing, just use the name of the function (without the () list of parameters) e.g.
double(*f_to_cal)(double);
f_to_cal = sin; /* trigonometric sine function */
return f_to_cal(angle_deg * M_PI / 180.0);

Why does it seem that func is the same as &func in C? [duplicate]

This question already has answers here:
How does dereferencing of a function pointer happen?
(5 answers)
Closed 2 years ago.
According to the GNU C manual, functions can be called using function pointers like so:
func (j); /* (*func) (j); would be equivalent. */
So my reasoning here is: func itself is a pointer to the func(int) function. When you call func(j), you are implicitly accessing the value of the pointer func (you are moving to the memory location where func is), in the same way as when you have a pointer to an integer, for example, and you access the value stored in that position of the memory using *. That would be consistent with the fact that you can call that same function using (*func)(j).
In fact, in cprogramming.com, they say you can have a pointer to a pointer of a function. So I am therefore guessing they work like any other kind of pointers.
But if that's the case, why is it that this code works?
#include <stdlib.h>
#include <stdio.h>
void a(int n) {
printf("%d\n", num);
}
int main() {
int x = 5;
void (*func)(int); // Declare a pointer to a function
func = &a; // Pointer to a pointer to a function
(*func)(x); // Calls the function (why?)
func = a; // Pointer to a function
(*func)(x); // Calls the function (makes sense)
}
Moreover, if you call:
printf("%s\n", (&a == a) ? "True" : "False");
It prints True!
I am sure that &foo is not the same as &&foo, for example, so why does it seem to be the case that func is the same as &func?
N1570 6.3.2.1 Lvalues, arrays, and function designators says:
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’’.
Here a and *func are function designators because they have function type. a in &a is not converted to a pointer because it is the operand of the unary & operator and the pointer to the function is retrieved by the & operator.
On the other hand, a in func = a; is converted to the pointer to the function according to this rule.
Therefore a and &a in this code are equivalent.
Also func in func(x); is converted to the pointer according to this rule.
(*func)(x); is:
func is converted to the pointer according to this rule
The pointer is dereferenced by * in *func
*func is converted to the pointer according to this rule
Thus (*func)(x); is equivalent to func(x);.
A function designator used in expressions is implicitly converted to pointer to the function.
So for example you could call your function like
( **********a )( 5 );
That is in this expression *a the function designator a is converted to pointer to the function. Applying the dereference operator * you again get a function designator that in turn is converted to pointer to the function in the expression **a. And so on.
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
4 A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator65) 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’’.
So in this assignment
func = &a; // Pointer to a pointer to a function
there is used the operator & (see the quote from the C Standard) that means that the function designator a is not converted to function pointer in this expression. And you do not have pointer to a function pointer as you wrote in the comment to the statement above.
From the very documentation you've provided:
5.6 Calling Functions Through Function Pointers
You can also call a function identified by a pointer. The indirection operator * is optional when doing this.
#include <stdio.h>
void foo (int i)
{
printf ("foo %d!\n", i);
}
void bar (int i)
{
printf ("%d bar!\n", i);
}
void message (void (*func)(int), int times)
{
int j;
for (j=0; j<times; ++j)
func (j); /* (*func) (j); would be equivalent. */
}
void example (int want_foo)
{
void (*pf)(int) = &bar; /* The & is optional. */
if (want_foo)
pf = foo;
message (pf, 5);
}
So, The indirection operator * is optional when doing this. and /* The & is optional. */ comments says it all. They're optional. Why they are optional is explained by #MikeCat and #Vlad from Moscow

function pointer and memory address in C [duplicate]

This question already has answers here:
Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?
(5 answers)
Closed 3 years ago.
In the following program, &foo, *foo and foo points to the same memory adress :
#include <stdio.h>
int foo(int arg)
{
printf("arg = %d\n", arg);
return arg;
}
int main()
{
foo(0); // ok
(*foo)(0); // ok
(&foo)(0); // ok
printf("&foo = %lx\n", (size_t)(&foo));
printf("foo = %lx\n", (size_t)(foo));
printf("*foo = %lx\n", (size_t)(*foo));
return 0;
}
the output is :
arg = 0
arg = 0
arg = 0
&foo = 55eeef54c720
foo = 55eeef54c720
*foo = 55eeef54c720
Does anyone can explain this ?
Thank you.
In the terminology of the C standard, any expression that has function type is a function designator. So, when used as an expression, the name of a function is a function designator.
There is nothing you can do with a function designator except take its address. You cannot add a number to a function designator, you cannot compare it to another function designator, and so on. Of course, you can call a function, but this is actually done by address, not by designator, as I will explain in a moment. Since there is nothing you can do with a function except take its address, C does this for you automatically. Per C 2018 6.3.2.1 4:
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".
The result of this is:
In &foo, the & takes the address of foo, so &foo is the address of foo.
In foo, the function designator is automatically converted to the address of the function, so foo is &foo.
In *foo, the function designator is automatically converted to the address of the function. Then the * operator converts this back to the function, which produces a function designator. Then the automatic conversion happens again, and the function designator is converted back to the address of the function, so the result of *foo is &foo.
When you call a function, using the function ( argument-list... ) notation, the function must actually be a pointer to a function. Thus, you can call foo using (&foo)(arguments...). The automatic conversion simplifies the syntax so you can write foo(arguments...), but the call expression actually requires the address of the function, not the function designator.
Incidentally:
A proper printf specifier for size_t values is %zx, not %lx.
If you include <stdint.h>, it defines a type intended for converting pointers to integers, uintptr_t. This is preferably to converting pointers to size_t.
The function foo is implicitly convertible to a pointer to the function foo.
The unary & applied to a function yields a pointer to the function, just like it yields the address of variable when applied to a variable.
The unary * applied to a function pointer, yields the pointed-to function, just like it yields the pointed-to variable when it is applied to an ordinary pointer to a variable.
So here, foo is the same as &foo which is the same as *foo.
So *foo is same as *(&foo) which is the same as foo.

Why can function pointers be used with or without the address of operator? [duplicate]

This question already has answers here:
Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?
(5 answers)
Closed 4 years ago.
In the book, "Beginning C from Novice to Professional", the author does not use the address of operator when assigning a function to a function pointer. I typed in the code on my compiler both with and without the address of operator and it compiled and performed as expected both times. Why is this and which way would be preferred in an enterprise/business setting?
int sum(int, int);
int main(void)
{
...
int (*pfun)(int, int);
pfun = ∑
pfun = sum;
...
}
int sum(int x, int y)
{
return x + y;
}
This is a peculiarity of functions in C. The C standard says the following (C11 3.4.1p4):
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''.
I.e. sum that is a function designator is in any expression context, except when preceded by & or the said 2 operators is converted to a pointer to function. Of course in the expression &sum, the result is a pointer to a function. And ISO C does not allow sizeof or _Alignof be applied to a function, so in any expression that compiles, a function designator is either implicitly, or in the case of address-of operator, explicitly converted to a pointer to a function.
Even the function call operator () requires that its operand be a pointer to function, hence you can call pfun without dereferencing: pfun(1, 2); and in sum(1, 2) sum is first converted to a pointer to a function, and then the function call operator is applied to this pointer.
There are coding conventions that say that a call through a function pointer should use the dereference operator *, i.e. (*pfun)(1, 2), and likewise that the assignment be written as pfun = ∑.
As such, writing (*pfun)(1, 2) would not make it clearer that it is a pointer as the same syntax would equally work for a function designator, i.e. (*sum)(1, 2); in the latter, sum is first converted to a pointer to a function since it is an operand to *; then the dereference converts the pointer to function to a function designator again, and then since it is an operand to a function call operator, it is converted to a function pointer again.
Lastly, beware that pfun being an object of function pointer type, &pfun would actually get the address of the pointer variable, which is almost never what you wanted.

In C why can I pass function name (not a pointer) as parameter to funtion? [duplicate]

This question already has answers here:
Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?
(5 answers)
Closed 5 years ago.
I have test the following code:
#include <stdio.h>
void f(void g()) {
g();
}
void g(void) {
printf("hello, world\n");
}
int main() {
f(g);
return 0;
}
It works well. In the code above, why in c we can take the function name g as paramter and take the function prototype as parameter?
In book K&R, it says that we can use the pointer to function:
So I can define the function f like this:
void f(void (*g)()) {
g();
}
void g(void) {
printf("hello, world\n");
}
int main() {
void (*pf)() = g;
f(pf);
f(g); // Here f(g) also works.
return 0;
}
So in the first f definition form, the parameter prototype is void g(), in the second form the parameter prototype is void (*g)(). Why the two forms of definition of f are the same?
And in the second form, the parameter is a pointer to function, why f(g) also works?
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
4 A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator65) 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’’.
and (6.7.6.3 Function declarators (including prototypes))
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.
Thus these function declarations
void f(void g());
and
void f(void ( *g )());
declare the same one function.
Because a function decays into a function pointer when it is not used within a function calling context:
void f(void a()) { a(); } //void a() decays into void (*a)()
void g(void (*a)()) { a(); } //equivalent to the above
void h(void a()) { (*a)(); } //*a is equivalent to a
void i(void a()) { (**a)(); } //**a is equivalent to *a
void j(void a()) { (***a)(); } //...
void k() { };
int main() {
f(k);
g(k);
h(k);
i(k);
j(k);
}
This compiles and runs fine, even though I've been using liberal amounts of the dereferencing operator on the argument function. Each time I use it, the resulting function decays back into a pointer when it hits the next dereferencing operator. Likewise, the function argument void a() decays into a pointer just like int array[] decays into int* array when used as a function argument.
When used as a function parameter, function name behaves as a pointer to the function itself.
These all are valid prototype
void f(void (g)());
void f(void (*g)());
void f(void (**g)());
void f(void (*****g)());
When you declare a function pointer then you can make a call using that pointer as
g();
(*g)();
(*****g)();
The C standard ISO/IEC 9899:2011, section 6.3.2.1 item 4 says:
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”.
So normally a function name (or other expression with function type, i.e. a function designator) is converted to a pointer to a function, except in the circumstances mentioned above.
So what happens when you apply the & operator to a function, as that is one of the cases excluded from the above clause. The answer is given by section 6.5.3.3 item 3, the relevant parts of which are:
The unary & operator yields the address of its operand. If the operand has type “type”, the result has type “pointer to type”. [...] Otherwise, the result is a pointer to the object or function designated by its operand.
(The "[...]" part I missed out discusses applying the & operator to the result of a unary * operator and to the result of the [] operator.)
So applying & to a function name (or other function designator) also gives you a pointer to the function.
So what happens when you dereference a function pointer with the unary * operator? It produces a function designator (section 6.5.3.3 item 4), which in most circumstances (as discussed above) gets converted back to a pointer to a function!
EDIT: I neglected to mention the case of declaring a parameter of a function to be a function returning type. As discussed in Vlad from Moscow's answer referring to section 6.7.6.3 item 8, that gets automatically adjusted to be a pointer to a function returning type.

Resources