Ошибка invalid use of void expression

I have a function int rt_task_start (RT_TASK *task, void(*task_func)(void *arg), void *arg)
where in second argument i am passing a function with argument.

  1. When i only pass a function name at that time there is no problem.(as expected it’s working). rt_task_start(&demo_task1, demo, 1);
  2. But when i pass rt_task_start(&demo_task1, demo(&val), 1); it’s giving me error error: invalid use of void expression. Variable val is defined before. int val = 0;
  3. When i call with this rt_task_start(&demo_task1, demo(val), 1); this is showing error Warning passing argument 1 of 'demo' makes pointer from integer without a cast then error: invalid use of void expression.
  4. int *val;
    *val = 0;

    rt_task_start(&demo_task1, demo(&val), 1); this is also giving me error.

I can’t understand what should i pass, as a void pointer. It’s giving me error. Any Idea Please!

asked Mar 29, 2014 at 13:57

Arun Gupta's user avatar

2

void (*task_func)(void *arg);

The above statement defines task_func to be a pointer to a function which takes a pointer of type void * and returns no value.

Therefore, when you call your function rt_task_start, you should pass a pointer to a function as the second argument. Also, you should pass a pointer of type void * as the third argument, not an integer. A function name evaluates to a pointer to the function, so you can simply pass the function name as the argument value, or you can use the address-of operator & before the function name.

int arg = 4;

// both calls are equivalent

rt_task_start(&demo_task1, demo, &arg);
rt_task_start(&demo_task1, &demo, &arg);

answered Mar 29, 2014 at 14:07

ajay's user avatar

ajayajay

9,3928 gold badges44 silver badges71 bronze badges

I’m not sure how the code in (1) can possibly compile. But here is what you should be using:

int rt_task_start (RT_TASK *task, void(*task_func)(void *arg), void *arg);
int val = 1;
rt_task_start(&demo_task1, demo, &val);

You cannot pass the function pointer bound to a specific argument, that is something like a closure, which isn’t available in C. You can, however, pass the function pointer and then separately pass the argument you want to apply (which is what the function signature suggests you should do). But you must pass that argument as a pointer, not a literal.

answered Mar 29, 2014 at 14:07

Jeremy West's user avatar

Jeremy WestJeremy West

11.3k1 gold badge17 silver badges25 bronze badges

Surely you want:

  int i=1;
  rt_task_start(&demo_task1, demo, (void*) &i);

Just by matching the argument types, remember the second argument is just a function pointer, not a function call with its own argument, it’s own argument is only used when you call it within rt_task_demo. If you then want to use the value ‘1’ in function ‘rt_task_demo’ you would recast it like

int ii = *(int*) arg;

answered Mar 29, 2014 at 14:15

user3353819's user avatar

user3353819user3353819

9112 gold badges8 silver badges21 bronze badges

Trusted answers to developer questions

Free System Design Interview Course

Many candidates are rejected or down-leveled due to poor performance in their System Design Interview. Stand out in System Design Interviews and get hired in 2023 with this popular free course.

The “invalid use of void expression” error occurs in C/C++ when we try to assign a call to a void function to a variable. It also occurs when a void function is cast to another data type.

Code

In the following code, the function f() has a void return type. This function is passed as an argument to the function g(), which expects an int as its argument. C++ tries to cast the void return type of the function f() to an integer, which causes the “invalid use of void expression” error.

#include <iostream>

using namespace std;

void f()

{

cout<<"Hello World"<<endl;

}

int g(int k)

{

return (k+5);

}

int main()

{

int x = g(f());

cout<<x<<endl;

}

Solution

The solution is to avoid casting void return types to any other data type. Since the function g() can only accept an integer data type, we should only pass it data of integer data type.

#include <iostream>

using namespace std;

void f()

{

cout<<"Hello World"<<endl;

}

int g(int k)

{

return (k+5);

}

int main()

{

f();

int x = g(5);

cout<<x<<endl;

}

RELATED TAGS

void

expression

invalid

c++

error

Copyright ©2023 Educative, Inc. All rights reserved

I’m defining an attachinterrupt and I’m running into an error. The line in question is:

void setup() {
   attachInterrupt(digitalPinToInterrupt(stallsense1), changedirection(1), RISING);
   attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
}

and the error I’m getting is:

error: invalid use of void expression
attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
                                                                                ^
exit status 1
invalid use of void expression

The idea is I have one function changedirection and two possible inputs, either 1 or 2.
I believe the issue is where I’ve called the function changedirection(1). I want to simply tell attachinterrupt to call the function changedirection with an input of either 1 or 2. How would I do this?

jsotola's user avatar

jsotola

1,3632 gold badges10 silver badges19 bronze badges

asked Jun 17, 2021 at 22:58

Jules's user avatar

attachInterrupt expects a simple pointer to function taking no arguments and returning nothing (void).

So, really there’s no way to directly do what you’re talking about. There’s no currying ability builtin. You can define your own functions like

void proxy_changedirection_1() {
    changedirection(1);
}

And then attachInterrupt specifying proxy_changedirection_1, or you can use a lambda with no captures for the same purpose:

attachInterrupt(
    digitalPinToInterrupt(stallsense1),
    [] () {
        changedirection(1);
    },
    RISING
);

answered Jun 17, 2021 at 23:17

timemage's user avatar

timemagetimemage

4,7591 gold badge10 silver badges24 bronze badges

1

What happened is you wrote a void expression where an expression of type ‘pointer to function of void returning void’ (i.e., no arguments and no return value), was expected. The name of a function with no parentheses for an argument list is an expression of type ‘pointer to function’ taking whatever arguments & types that named function was declared to expect, and returning whatever type that named function was declared to return.

But if you write the parentheses with it, now you’ve written an expression that 1) would (if it were valid) get evaluated during the call to attachInterrupt() — much earlier that you want it to be! — and return a value of that return type rather than the type you expected.

@timemage has offered two ways to solve this.

answered Jun 17, 2021 at 23:34

JRobert's user avatar

JRobertJRobert

14.9k3 gold badges21 silver badges51 bronze badges

Arduino Forum

Loading

  • Forum
  • Beginners
  • error: invalid use of void expression

error: invalid use of void expression

CodeBlocks…
warning: dereferencing ‘void *’ pointer [enabled by default]|
error: invalid use of void expression

I believe i do not know how to properly use the generic void* pointer. I want to pass data to pointer to void so that to be able to manipulate any type of data the user wants to use. The functions below is just a test to show my intentions.
I am using only c language syntax. I do not want c++ syntax for these.

I have asked a very similar question in the past but i did not quite get it. It was not the kind of response i was hoping for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int foo(void* x, void* y)
{
    *x  = 3;
    *y = *x + 1;
    return 0;
}

void* foo1( void* x)
{ *x = *x +1; }
 
int main(void)
{
    int a=7;
    int b = 5;
    char c = 'a';
    foo(&a,&b);
    printf("%dn%dn",a,b);

    foo1(&c);
    printf("%cn",c);
    
}

e]

In function ‘int foo(void*, void*)’:
5:6: error: ‘void*’ is not a pointer-to-object type
6:6: error: ‘void*’ is not a pointer-to-object type
6:11: error: ‘void*’ is not a pointer-to-object type
In function ‘void* foo1(void*)’:
11:4: error: ‘void*’ is not a pointer-to-object type
11:9: error: ‘void*’ is not a pointer-to-object type
11:15: warning: no return statement in function returning non-void [-Wreturn-type]

Normally when using void pointers, one has to cast the pointer to a type.

http://stackoverflow.com/questions/16986214/why-type-cast-a-void-pointer#16986872

When doing some kind of operation on data the compiler needs to know the type, otherwise it doesn’t know what machine code to generate. For example, addition between two signed 32-bit integers uses a different CPU instruction than addition between two unsigned 16-bit integers, or between two floating point numbers. Addition between two class types requires that the correct overload of operator+ is called, but if the compiler doesn’t know the types there is no way it could know which overload to call.

If you can use C++ features you might find function templates useful. The compiler will then be able to automatically generate code (at compile time) for each type that you pass to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

template <typename T>
int foo(T* x, T* y)
{
    *x  = 3;
    *y = *x + 1;
    return 0;
}

template <typename T>
T* foo1(T* x)
{
    *x = *x +1;
    return x;
}
 
int main(void)
{
    int a=7;
    int b = 5;
    char c = 'a';
    foo(&a,&b); // calls foo<int>
    printf("%dn%dn",a,b);

    foo1(&c); // calls foo1<char>
    printf("%cn",c);
}

Last edited on

Cast your pointer to the desired type before manipulating it.

The problem with foo() is that there are non-enforceable requirements on the real type of the pointed-to object. You either need to know the type is (i.e., by passing it in as a macro parameter or via a printf-style specifier), or you need to make assumptions about the type based on its size, and you’d have to pass the size in.

The real solution is to not use void* here. Generic programming in C is awful.

Is something like this what you’re thinking of?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* Some way to signal the real type of an argument.  Such a type is analogous to
   printf's format string -- that's one way to signal type too. */
/* User-defined structures will need to be handled through a proxy function */
typedef enum TypeLabel { Char_T, SChar_T, UChar_T, Int_T, UInt_T, /* ... */ } TypeLabel;
void increment(TypeLabel c, void* x) {
# if ! defined BRANCH
# define BRANCH(label, type) do {                      
    /* Manipulate x here */                            
    case label: *((type*)x) = (*(type*)x) + 1; return; 
  } while(0)

  switch (c) {
    BRANCH(Char_T , char);
    BRANCH(SChar_T, signed char);
    BRANCH(UChar_T, unsigned char);
    BRANCH(Int_T  , int);
    BRANCH(UInt_T , unsigned int);
    /* ... */
  }
# else
# error "BRANCH already defined"
# endif 
}

# include <stdio.h>
int main(void) {
  int bar = 3;
  increment(Int_T, &bar);
  printf("%dn", bar);
}

http://coliru.stacked-crooked.com/a/5c5f42258e8f2c92

Last edited on

Topic archived. No new replies allowed.

  • Ошибка invalid use of this in non member function
  • Ошибка invalid use of non static data member
  • Ошибка invalid use of incomplete type class ui mainwindow
  • Ошибка invalid use of incomplete type class qdebug
  • Ошибка invalid stfs package horizon что делать