-1

I cannot understand why different code works as it will be identical.

#include <stdio.h>

void foo() {
    printf("Hello\n");
}

void foo1(void fn()) {
    (*fn)();
    fn();
}

void foo2(void (*fn)()) {
    (*fn)();
    fn();
}

int main(void) {
    foo1(foo);
    foo2(foo);
    return 0;
}

If they identical then why this does not work?

typedef void F1(), (*F2)();

int main(void) {
    F1 f1;
    F2 f2;
    // error: lvalue required as left operand of assignment
    f1 = foo1;
    f2 = foo2;
    return 0;
}

P.S.

My interest are not in the typedef (second example).
I have questions only about the first example.
That is:

  • Function declartions
  • Function invocations
user3386109
  • 34,287
  • 7
  • 49
  • 68
mezoni
  • 10,684
  • 4
  • 32
  • 54

2 Answers2

1

You are using the typedef incorrectly. The first F1() is not a function pointer at all. Your second part does correctly provide a typedef for a function pointer (*F2)(), but you fail to include a type. Bottom line, but you don't get 2 function pointer typedefs in one line:

typedef void (*F1)();
typedef void (*F2)();

Will create both a typedef for F1 and a typedef for F2.

As far as the use of the function pointers, the function pointers may be used with, or without, parens and the dereference.

(*fn)();
fn();

Both are equivalent and simply call the function pointed to by fn.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Ok, I'll have a look. – David C. Rankin Apr 22 '15 at 08:19
  • I need a reference to documenation as the answer. – mezoni Apr 22 '15 at 08:20
  • I'll find a reference, it will take a few minutes. – David C. Rankin Apr 22 '15 at 08:23
  • @mezoni I looked through the **C11** standard and could not find a direct statement addressing the situation. There is no ambiguity in the two forms of the call, because it is clear that both refer to an address holding a function call. A secondary reference explains the use here [**Programs as Data: Function Pointers**](http://www.cprogramming.com/tutorial/function-pointers.html) – David C. Rankin Apr 22 '15 at 08:51
1

The lines

typedef void F1();
F1 f1;

do not declare f1 as a pointer. They declare f1 as a function returning void. The equivalent declaration is

void f1();

This can be demonstrated by the following code, which will compile without any errors or warnings. Note that if you comment out the line F1 f1;, then the compiler will complain about "implicit declaration of function f1" and "conflicting types for f1" because you have a forward reference without a declaration.

typedef void F1();

int main(void)
{
    F1 f1;
    f1();
    return 0;
}

void f1()
{
    printf( "hello\n" );
}

On the other hand, the following code will also compile without warning or error, but in this case the compiler treats f1 like a pointer to a function.

typedef void F1();

void foo() {
    printf( "hello\n" );
}

void foo1(F1 f1) {
    f1();
}

int main(void) {
    foo1( foo );
    return 0;
}

Why the difference? Because §6.7.6.3 Function declarators, paragraph 8 reads

A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type", as in 6.3.2.1.

user3386109
  • 34,287
  • 7
  • 49
  • 68