14

I know void (*)(int) is to function pointer but what is void(int)?

It's used for std::function template.

Say I have a function void fun(int){} : decltype(&fun) gives void(*)(int) but decltype(fun) gives void(int)

Soapy
  • 557
  • 14
  • 29
Derek
  • 557
  • 1
  • 4
  • 16
  • 3
    [callback function: difference between `void(*func)(int)` and `void(func)(int)`](http://stackoverflow.com/q/25953542/995714) – phuclv Dec 23 '15 at 14:19
  • @LưuVĩnhPhúc if you believe this is a duplicate, you should flag it as such – acupofjose Dec 23 '15 at 14:20
  • 1
    It isn't a duplicate. That question is about a function parameter that is declared with a function type. – interjay Dec 23 '15 at 14:23
  • Related (not duplicate, though the answer mentions function types in passing): [Function pointer vs Function reference](http://stackoverflow.com/q/19200513/364696) – ShadowRanger Dec 23 '15 at 14:26

3 Answers3

17

If T is a type, then T* denotes the type "pointer-to-T".

The type void(int) is a function type, it's the type of a function taking one int and returning void. For example, it is the type of f if f is declared as void f(int);

If T = void(int), then T* is spelled void(*)(int), so the latter is the type of a function pointer. You can also form a reference to a function, which is T& = void(&)(int); this is occasionally more useful (e.g. you can take the address of a function lvalue).


Aside note: Function lvalues decay to their function pointer very easily. You can call a function either via a function lvalue or via a function pointer. When used as an operand for the indirection operator (*), the function value decays, so you can dereference the pointer again and again:

printf("Hello world\n");        // OK
(*printf)("Hello world\n");     // also OK
(****printf)("Hello world\n");  // four-star programmer

Some of the only times that a function does not decay is when used as the operand of the address-of operator, or when bound to a reference:

void f(int);          // our example function

void(*p1)(int) = &f;  // no decay of "f" here
void(*p2)(int) = f;   // "f" decays
void(&r1)(int) = f;   // no decay of "f" here

void g(void(&callback)(int), int n) {
  callback(n);
}
g(f, 10);             // no decay of "f" here

template <typename F, typename ...Args>
decltype(auto) h(F&& callback, Args&&... args) {
    return std::forward<F>(callback)(std::forward<Args>(args)...);
}
h(f, 10);             // no decay of "f" here
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Note: In (just about?) every scenario but C++ template substitution and the trivial case of "calling a function directly", [a function type degrades to a function pointer when used](http://stackoverflow.com/a/19200555/364696), so there is no difference. And I'd suspect in the template case, where the function is part of the template definition, the compiler would inline and undo the function pointeriness if it can (if it's not actually using a variable storing a non-constexpr function pointer). – ShadowRanger Dec 23 '15 at 14:30
  • can I have a var of type void(int), and how to assign a value to it? – Derek Dec 23 '15 at 14:36
  • @Derek: No, you cannot have variables of function type, you cannot have prvalues of function type, and the return value of a function must not be a function type. – Kerrek SB Dec 23 '15 at 14:39
  • @Derek: You can't have a variable of type `void(int)`, but you can have a *function* of that type. – Martin Bonner supports Monica Dec 23 '15 at 14:45
8
void (*whatever)(int) 

should be read as: whatever is a pointer, pointing to a function, that accepts one int as argument, and returns nothing (ie., void).

void whatever(int)

should be read as: whatever is a function (NOT a pointer), that accepts one int as argument, and returns nothing (ie., void)

Once the pointer to a function is initialized to point to a valid function (one that satisfies the prototype), then you can invoke the function either through its "real" name, or through the pointer.

Pointers to functions are very useful - they're variables, just like anything else, so you can pass them around to other functions (see e.g. qsort()), you can put them in structs, etc..

Given this, the following code is valid:

#include <stdio.h>

void myfun(int x) {
  printf("The value of X is %d\n", x);
}

int main() {
    void (*myfunp)(int);

    myfunp = &myfun;

    myfun(13);
    myfunp(12);

    return 0;
}
Karel Kubat
  • 1,635
  • 11
  • 12
3

void(*)(int) should be read as type of a pointer which is pointing to a function, that accepts one int as argument, and returns nothing.

For understanding more on function to pointer and its usage please check here: http://www.cprogramming.com/tutorial/function-pointers.html

Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256