user23860: Edit:
I tried a simple code in Arduino IDE which should've done in the first place instead in doing it in a desktop compiler. Because the results are different by experiment. In the desktop C compiler, it's working and bypassing the code without much problems, just one or two warnings.
But in Arduino IDE, it's not acceptable and gives error.
This is the code:
// functions
void function1(uint8_t x, uint8_t y){
  int z = x + y;
  Serial.println("function1\n");
  Serial.println(z);
}
uint8_t function2(uint8_t x, uint8_t y){
    Serial.println("function2\n");
    return 1;
}

void (*fun_ptr)();

void setup() {
  // put your setup code here, to run once:
  
  Serial.begin(9600);
  fun_ptr = (void (*)())function2;
  int value;
  
  value = fun_ptr(1,2);

}

void loop() {
  // put your main code here, to run repeatedly:

}


user7508: It looks to me like you are trying to find the right answer to the wrong
question, typical of an XY problem. In the example you provide in
your own answer, you call the function pointer right after having set
its value. In this case, there is no use to the function pointer, as you
could directly call either read_chars() or write_chars().
Obviously, this is just because that example is excessively simplified.
In a more realistic use case, you would set the function pointer in one
part of the code, and call it in a completely different part. Assuming
the functions and the pointer are defined like this:
void (*fun_ptr)();

void read_chars(uint8_t address) {
    printf("address of array is 0x%.2x\n", address);
}

void write_chars(uint8_t row, uint8_t col, const char *str) {
    printf("[%d, %d]: %s\n", row, col, str);
}

One section of the program sets the pointer:
// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = (void(*)()) read_chars;
} else {  // should write
    fun_ptr = (void(*)()) write_chars;
}

and a different section calls it:
// Here we have to perform the action.
if (fun_ptr == (void(*)()) read_chars) {
    ((void(*)(uint8_t)) fun_ptr)(1);
} else if (fun_ptr == (void(*)()) write_chars) {
    ((void(*)(uint8_t, uint8_t, const char *)) fun_ptr)(
            1, 1, "messaage0");
}

Note that this second section must know what function it is calling
in order to pass the correct arguments. Hence the if...then test. Note
also that, in order to have valid C++, you must explicitly cast the
function pointer before calling it. This gets very clumsy, and it is a
lot more convenient to store this information (what function should be
called) in an enum rather than a function pointer:
enum {
    CALL_NONE, CALL_READ_CHARS, CALL_WRITE_CHARS
} what_to_call = CALL_NONE;

which would be used like this:
// Here we learn what action should be performed.
if (should_read()) {
    what_to_call = CALL_READ_CHARS;
} else {
    what_to_call = CALL_WRITE_CHARS;
}

// ...

// Here we have to perform the action.
if (what_to_call == CALL_READ_CHARS)
    read_chars(1);
else if (what_to_call == CALL_WRITE_CHARS)
    write_chars(1, 1, "messaage1");

That being said, it is often the case that when it is time to perform
the action, the part of the code responsible of doing so does not know
what arguments should be passed, and this information is more readily
available at the time when when learn what action should be performed.
This is a quite common situation, and a standard C idiom in this case is
to give the function a void * parameter that it will cast to the
appropriate type in order to retrieve the data it needs. For instance:
void (*fun_ptr)(void *);
void *fun_ptr_data;

void read_chars(void * data) {
    uint8_t address = * (uint8_t *) data;
    printf("address of array is 0x%.2x\n", address);
}

struct write_chars_data {
    uint8_t row;
    uint8_t col;
    const char *str;
};

void write_chars(void *data) {
    write_chars_data *d = (write_chars_data *) data;
    printf("[%d, %d]: %s\n", d->row, d->col, d->str);
}

Note that, since write_chars() needs to retrieve multiple parameters
from a single pointer, it uses a pointer to a struct.
Now, the part of the code that learns what should be done has the
responsibility of providing the data:
// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = read_chars;
    uint8_t *p = new uint8_t;
    *p = 1;
    fun_ptr_data = (void *) p;
} else {  // should write
    fun_ptr = write_chars;
    write_chars_data *p = new write_chars_data;
    p->row = 1;
    p->col = 1;
    p->str = "messaage2";
    fun_ptr_data = (void *) p;
}

The part of the code that has to perform the action now is very simple:
// Here we have to perform the action.
if (fun_ptr)
    fun_ptr(fun_ptr_data);

Note that this code snippet doesn't free the allocated memory. You will
have to figure out who will be responsible for that.
This pattern is quite common in libraries, where the client (the user of
the library) wants an action to be performed, but the library is
responsible for performing that action at the right time. The client
would then provide the library a pointer to a function that accomplishes
the action (called a “callback”), together with a generic pointer to the
data needed by the callback. The use of a generic void * pointer makes
sense, because the library cannot know what kind of data the callback
will need.
In your case, since you know what kind of data you may need, you could
use a pointer to an union instead of a generic pointer:
union fun_data {
    uint8_t address;  // for read_chars
    struct {          // for write_chars
        uint8_t row;
        uint8_t col;
        const char *str;
    };
};

void (*fun_ptr)(fun_data *);
fun_data *fun_ptr_data;

A more idiomatic C++ style would be to pack together the callback
function and its data into a “functor”, i.e. an object that can be
called like a function, and can also store the data it needs. You would
then use inheritance in order to create specific functor types while
calling a generic one.

user42015: I assume, that the fun_ptr points to the different service functions to do some kind of animation other other long running tasks on your display, thus you want to repeatedly call them in a structured way.
What you are currently doing will not really work. When you call a function, you need to provide its arguments. That's the same for a function pointer. You cannot call a function, that demands parameters, without any parameters. While you can still set a function pointer of type (void (*)(void*) to a function of type (void (*)(uint8_t)), the compiler warns so, because you still cannot call the function without any parameter. If you are trying to do so, you will still get an error of too few arguments to function ....
I see 2 ways to go from here:

You could overload your functions, so that a version without any parameters exists. Like this:
  void foo(uint8_t i){Serial.println(i);}
  void foo(){foo(10);}

With 10 being the value, with which the function should be called, when you provide no parameters. You can of course also use variables or function calls here, to actually get that value for the parameter i. Then you can use the pointer to call that function:
  void (* p)(void);
  p = &foo;
  p();

The assignment of the pointer will choose the version of the function without any parameters out of the overloaded pool of this function, since that matches the type of the pointer. Note, that I removed the * from the void parameter definition. I don't understand, what that would mean anyway (pointer to void?). The function pointer p() can now be called without any parameters, since it points to a function without any parameters.

You could ditch the function pointer and use a simple switch case statement with a state variable (which holds some identifier for the corresponding function), to call the correct service function. I won't go into detail here, since that is already basically, how an FSM can be programmed in C++, which is covered on this site and on the web numerous times.


If I were you, I probably would go with the first option, though that might also depend on the overall logic, that I currently don't really understand (too few information).

23860: <p><strong>Edit:</strong>
I tried a simple code in Arduino IDE which should've done in the first place instead in doing it in a desktop compiler. Because the results are different by experiment. In the desktop C compiler, it's working and bypassing the code without much problems, just one or two warnings.</p>
<p>But in Arduino IDE, it's not acceptable and gives error.</p>
<p>This is the code:</p>
<pre><code>// functions
void function1(uint8_t x, uint8_t y){
  int z = x + y;
  Serial.println(&quot;function1\n&quot;);
  Serial.println(z);
}
uint8_t function2(uint8_t x, uint8_t y){
    Serial.println(&quot;function2\n&quot;);
    return 1;
}

void (*fun_ptr)();

void setup() {
  // put your setup code here, to run once:
  
  Serial.begin(9600);
  fun_ptr = (void (*)())function2;
  int value;
  
  value = fun_ptr(1,2);

}

void loop() {
  // put your main code here, to run repeatedly:

}
</code></pre>
 7508: <p>It looks to me like you are trying to find the right answer to the wrong
question, typical of an <a href="https://xyproblem.info/" rel="nofollow noreferrer">XY problem</a>. In the example you provide in
your own answer, you call the function pointer right after having set
its value. In this case, there is no use to the function pointer, as you
could directly call either <code>read_chars()</code> or <code>write_chars()</code>.</p>
<p>Obviously, this is just because that example is excessively simplified.
In a more realistic use case, you would set the function pointer in one
part of the code, and call it in a completely different part. Assuming
the functions and the pointer are defined like this:</p>
<pre class="lang-cpp prettyprint-override"><code>void (*fun_ptr)();

void read_chars(uint8_t address) {
    printf(&quot;address of array is 0x%.2x\n&quot;, address);
}

void write_chars(uint8_t row, uint8_t col, const char *str) {
    printf(&quot;[%d, %d]: %s\n&quot;, row, col, str);
}
</code></pre>
<p>One section of the program sets the pointer:</p>
<pre class="lang-cpp prettyprint-override"><code>// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = (void(*)()) read_chars;
} else {  // should write
    fun_ptr = (void(*)()) write_chars;
}
</code></pre>
<p>and a different section calls it:</p>
<pre class="lang-cpp prettyprint-override"><code>// Here we have to perform the action.
if (fun_ptr == (void(*)()) read_chars) {
    ((void(*)(uint8_t)) fun_ptr)(1);
} else if (fun_ptr == (void(*)()) write_chars) {
    ((void(*)(uint8_t, uint8_t, const char *)) fun_ptr)(
            1, 1, &quot;messaage0&quot;);
}
</code></pre>
<p>Note that this second section <strong>must</strong> know what function it is calling
in order to pass the correct arguments. Hence the <code>if...then</code> test. Note
also that, in order to have valid C++, you must explicitly cast the
function pointer before calling it. This gets very clumsy, and it is a
lot more convenient to store this information (what function should be
called) in an <code>enum</code> rather than a function pointer:</p>
<pre class="lang-cpp prettyprint-override"><code>enum {
    CALL_NONE, CALL_READ_CHARS, CALL_WRITE_CHARS
} what_to_call = CALL_NONE;
</code></pre>
<p>which would be used like this:</p>
<pre class="lang-cpp prettyprint-override"><code>// Here we learn what action should be performed.
if (should_read()) {
    what_to_call = CALL_READ_CHARS;
} else {
    what_to_call = CALL_WRITE_CHARS;
}

// ...

// Here we have to perform the action.
if (what_to_call == CALL_READ_CHARS)
    read_chars(1);
else if (what_to_call == CALL_WRITE_CHARS)
    write_chars(1, 1, &quot;messaage1&quot;);
</code></pre>
<p>That being said, it is often the case that when it is time to perform
the action, the part of the code responsible of doing so does not know
what arguments should be passed, and this information is more readily
available at the time when when learn what action should be performed.
This is a quite common situation, and a standard C idiom in this case is
to give the function a <code>void *</code> parameter that it will cast to the
appropriate type in order to retrieve the data it needs. For instance:</p>
<pre class="lang-cpp prettyprint-override"><code>void (*fun_ptr)(void *);
void *fun_ptr_data;

void read_chars(void * data) {
    uint8_t address = * (uint8_t *) data;
    printf(&quot;address of array is 0x%.2x\n&quot;, address);
}

struct write_chars_data {
    uint8_t row;
    uint8_t col;
    const char *str;
};

void write_chars(void *data) {
    write_chars_data *d = (write_chars_data *) data;
    printf(&quot;[%d, %d]: %s\n&quot;, d-&gt;row, d-&gt;col, d-&gt;str);
}
</code></pre>
<p>Note that, since <code>write_chars()</code> needs to retrieve multiple parameters
from a single pointer, it uses a pointer to a <code>struct</code>.</p>
<p>Now, the part of the code that learns what should be done has the
responsibility of providing the data:</p>
<pre class="lang-cpp prettyprint-override"><code>// Here we learn what action should be performed.
if (should_read()) {
    fun_ptr = read_chars;
    uint8_t *p = new uint8_t;
    *p = 1;
    fun_ptr_data = (void *) p;
} else {  // should write
    fun_ptr = write_chars;
    write_chars_data *p = new write_chars_data;
    p-&gt;row = 1;
    p-&gt;col = 1;
    p-&gt;str = &quot;messaage2&quot;;
    fun_ptr_data = (void *) p;
}
</code></pre>
<p>The part of the code that has to perform the action now is very simple:</p>
<pre class="lang-cpp prettyprint-override"><code>// Here we have to perform the action.
if (fun_ptr)
    fun_ptr(fun_ptr_data);
</code></pre>
<p>Note that this code snippet doesn't free the allocated memory. You will
have to figure out who will be responsible for that.</p>
<p>This pattern is quite common in libraries, where the client (the user of
the library) wants an action to be performed, but the library is
responsible for performing that action at the right time. The client
would then provide the library a pointer to a function that accomplishes
the action (called a “callback”), together with a generic pointer to the
data needed by the callback. The use of a generic <code>void *</code> pointer makes
sense, because the library cannot know what kind of data the callback
will need.</p>
<p>In your case, since you know what kind of data you may need, you could
use a pointer to an <code>union</code> instead of a generic pointer:</p>
<pre class="lang-cpp prettyprint-override"><code>union fun_data {
    uint8_t address;  // for read_chars
    struct {          // for write_chars
        uint8_t row;
        uint8_t col;
        const char *str;
    };
};

void (*fun_ptr)(fun_data *);
fun_data *fun_ptr_data;
</code></pre>
<p>A more idiomatic C++ style would be to pack together the callback
function and its data into a “functor”, i.e. an object that can be
called like a function, and can also store the data it needs. You would
then use inheritance in order to create specific functor types while
calling a generic one.</p>
 42015: <p>I assume, that the <code>fun_ptr</code> points to the different service functions to do some kind of animation other other long running tasks on your display, thus you want to repeatedly call them in a structured way.</p>
<p>What you are currently doing will not really work. When you call a function, you need to provide its arguments. That's the same for a function pointer. You cannot call a function, that demands parameters, without any parameters. While you can still set a function pointer of type <code>(void (*)(void*)</code> to a function of type (void (*)(uint8_t)), the compiler warns so, because you still cannot call the function without any parameter. If you are trying to do so, you will still get an error of <code>too few arguments to function ...</code>.</p>
<p>I see 2 ways to go from here:</p>
<ul>
<li><p>You could overload your functions, so that a version without any parameters exists. Like this:</p>
<pre><code>  void foo(uint8_t i){Serial.println(i);}
  void foo(){foo(10);}
</code></pre>
<p>With 10 being the value, with which the function should be called, when you provide no parameters. You can of course also use variables or function calls here, to actually get that value for the parameter <code>i</code>. Then you can use the pointer to call that function:</p>
<pre><code>  void (* p)(void);
  p = &amp;foo;
  p();
</code></pre>
<p>The assignment of the pointer will choose the version of the function without any parameters out of the overloaded pool of this function, since that matches the type of the pointer. Note, that I removed the <code>*</code> from the <code>void</code> parameter definition. I don't understand, what that would mean anyway (pointer to void?). The function pointer <code>p()</code> can now be called without any parameters, since it points to a function without any parameters.</p>
</li>
<li><p>You could ditch the function pointer and use a simple switch case statement with a state variable (which holds some identifier for the corresponding function), to call the correct service function. I won't go into detail here, since that is already basically, how an FSM can be programmed in C++, which is covered on this site and on the web numerous times.</p>
</li>
</ul>
<p>If I were you, I probably would go with the first option, though that might also depend on the overall logic, that I currently don't really understand (too few information).</p>
