Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function Pointers (ambigous syntax) [duplicate]

In the following code:

/* mylog.c */
#include <stdio.h>
#include <stdlib.h> /* for atoi(3) */

int mylog10(int n)
{
    int log = 0;
    while (n > 0)
    {
        log++;
        n /= 10;
    }
    return log;
}

int mylog2(int n)
{
    int log = 0;
    while (n > 0)
    {
        log++;
        n >>= 1;
    }
    return log;
}

int main(int argc, const char* argv[])
{
    int (*logfunc)(int); /* function pointer */
    int n = 0, log;

    if (argc > 1)
    {
        n = atoi(argv[1]);
    }

    logfunc = &mylog10; /* is unary '&' operator needed? */

    log = logfunc(n);
    printf("%d\n", log);
    return 0;
}

in the line

logfunc = &mylog10;

I've noticed that the unary & (address of) operator is optional, and the program compiles and runs the same way either with or without it (in Linux with GCC 4.2.4). Why? Is this a compiler-specific issue, or perhaps two different language standards being accepted by the compiler? Thanks.

like image 307
pr1268 Avatar asked Sep 16 '26 10:09

pr1268


2 Answers

You are correct that the & is optional. Functions, like arrays, can be automatically converted into pointers. It's neither compiler-specific nor the result of different language standards. From the standard, Section 6.3.2.1, 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".

like image 169
Carl Norum Avatar answered Sep 17 '26 23:09

Carl Norum


Operator & is indeed optional when taking the address of a function in your context (assigning it to something). It is not compiler-specific, it follows from the formal definition of the language.

Symmetrically, operator * is optional when invoking the function through a pointer. In your example, you could invoke the function as either (*logfunc)(n) or logfunc(n). You used the latter, but the former would work as well.

like image 32
AnT Avatar answered Sep 18 '26 01:09

AnT