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.
- 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);
- But when i pass
rt_task_start(&demo_task1, demo(&val), 1);
it’s giving me errorerror: invalid use of void expression
. Variable val is defined before.int val = 0;
- When i call with this
rt_task_start(&demo_task1, demo(val), 1);
this is showing errorWarning passing argument 1 of 'demo' makes pointer from integer without a cast
thenerror: invalid use of void expression
. 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
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
ajayajay
9,3128 gold badges42 silver badges70 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 WestJeremy West
11k1 gold badge16 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
user3353819user3353819
8912 gold badges8 silver badges20 bronze badges
Trusted Answers to Developer Questions
Related Tags
void
expression
invalid
c++
error
Educative Answers Team
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
1,2142 gold badges10 silver badges18 bronze badges
asked Jun 17, 2021 at 22:58
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
timemagetimemage
4,6211 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
JRobertJRobert
14.7k3 gold badges19 silver badges49 bronze badges
0 / 0 / 0
Регистрация: 01.10.2019
Сообщений: 25
1
16.10.2019, 19:26. Показов 6517. Ответов 3
Здравствуйте. Необходимо написать программу которая вводит целое положительное число в промежутке от
1 до 100, которое определяет возраст человека. Сформировать записи трех видов:
Например,
«Ваш возраст 1 год», «Ваш возраст 22 года», «Ваш возраст 75 лет»
C | ||
|
Компилятор ругается
C | ||
|
В чем ошибка?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
- 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.
|
|
e]
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.
|
|
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?
|
|
http://coliru.stacked-crooked.com/a/5c5f42258e8f2c92
Last edited on
Topic archived. No new replies allowed.
Всем привет!
Нашел в интернете пример для создания программного таймера, всё отлично заработало. Функция его создания выглядит так:
enum StateTimer {IDLE, ACTIVE, DONE}; //состояния таймера - неработающий, активный, отработавший typedef struct{ unsigned long time; //через какое время сработает таймер unsigned int period; //период повторения enum StateTimer state; //текущее состояние void (*pFunc)(void); //указатель на функцию }SoftTimer; void CreateTimer(SoftTimer *CurSoftTimer, unsigned int time, unsigned int period, enum StateTimer state, void (*pFunc)()) { SoftTimers[AmountTimers] = CurSoftTimer; CurSoftTimer->time = time; CurSoftTimer->period = period; CurSoftTimer->state = state; CurSoftTimer->pFunc = pFunc; AmountTimers++; }
В качестве функции, которая будет вызываться, когда время таймера истечет я сначала использовал обычную, без аргумента. И создавал таймер вот таким образом:
CreateTimer(&Timer_CH1_Rise, timers_time[0], 0, IDLE, TimerDone); //создание таймера
Всё прекрасно работало, но теперь у меня возникла необходимость вызывать при сработке таймера функцию с аргументом и я делаю это вот таким образом:
CreateTimer(&Timer_CH1_Fall, timers_time[1], 0, IDLE, TimerDone(1)); //создание таймера
Однако Atmel Studio теперь ругается на эту строчку и выдает мне ошибку invalid use of void expression
Я понимаю что прикол кроется в указателях, но не могу разобраться самостоятельно что именно я делаю не так, помогите пожалуйста.
-
Помогите пожалуйста, с заданием:Переделайте программу так, чтобы устройство распознавало текстовые команды, например, «on» и «off», и соответственно включало и выключало светодиод.
C начала начну, пожалуй с команд «High» и «Low», а «on» и «off», потом условием поставлю! У меня где-то ошибка, а не пойму где…Код…#define LED_PIN 9
String message;
void setup()
{
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop()
{
while (Serial.available()) {
char incomingChar = Serial.read();
if (‘a’ <= incomingChar && incomingChar <=’z’) {
message += incomingChar;
} else if (incomingChar == ‘n’)
digitalWrite(LED_PIN, message.toLowerCase());
message = «»;
}
}
}Компилятор выдаёт ошибку: error: invalid use of void expression(Ошибка: неправильное использование пустот выражения)!Что это значит???
Может я не правильно использую метод «message.toLowerCase()»? -
Метод Вы используете не правильно, уже по той причине, что пытаетесь перевести сообщение не в верхний регистр, а в нижний.
Но даже это не поможет, потому что выражение digitalWrite(pin, value) принимает либо HIGH и LOW в момент написания программы для замены их компилятором, либо 0 либо 1(да и вообще любые числа) как значения переменных для работы с ними во время программы. -
Есть же хороший пример получения данных из COM порта и использования их как угодно. Можно разобраться и переписать под любую задачу.
-
Ну, да! Я как раз с ним и разбираюсь!И как раз у меня вопрос, почему компилятор выделяет мне строчку
digitalWrite(LED_PIN, message.toUpperCase());
и выдаёт ошибку: invalid use of void expression(Ошибка: неправильное использование пустот выражения)! Что это значит? О каких пустотах он говорит???
С верхним регистром тоже самое!
Это я понимаю! Я спрашиваю об ошибке » invalid use of void expression»!
-
В классе String метод toUpperCase определен как «void toUpperCase(void);», т.е. метод преобразует саму строку и не возвращает никакого результата. Следовательно, использовать его нужно так:
Но что эта строчка делает у вас в параметрах digitalWrite(), как она там вообще оказалась?
-
Да, действительно! Ошибка, в неправильном использовании. Всё теперь, я розобрался! В принципе ничего сложного, но нужно было почитать дополнительную информацию по классу String, и по его функциям. В самом эксперементе № 19, плохо описана эта тема, я несильно понял. Пришлось навёрстывать тут…
http://arduino.ua/ru/prog/
И ещё долго промучился, с тем что забыл считать символ «n»(enter, символ новой строки). И таки думал почему условие if (message == «ON») не выполняеться, оказалось if (message == «ONn») — всё решило!
Спасибо, всем кто ответил!
-
Только это неправильный способ. Нужно поменять условие в цикле чтения строки, чтобы символ перевода строки не оказывался внутри нее.
-
Ага, спасибо! Разобрался!
-
08-31-2012
#1
Registered User
«invalid use of void expression» error
Code:
#include<stdio.h> #include<stdlib.h> struct me { void **ptr; }*smith; int main() { int i,j; smith = malloc(sizeof(struct me)); smith->ptr=malloc(sizeof(void *) * 4); for(i=0;i<4;i++) { smith->ptr[i] = malloc(sizeof(void) * 5); } for(i=0;i<4;i++) { printf("address of ptr[%d] is %p and the value inside it is %p n",i,&smith->ptr[i],smith->ptr[i]); } for(i=0;i<4;i++) { for(j=0;j<5;j++) { printf("address of ptr[%d][%d] is %p and the value inside it is %d n",i,j,&smith->ptr[i][j],(int)smith->ptr[i][j]); } } return 0; }
I got «invalid use of void expression» error.
Please help to fix this error.
Thank youLast edited by smith283; 08-31-2012 at 08:21 AM.
-
08-31-2012
#2
C++ Witch
Basically, the sizeof(void) expression is invalid. You need to figure out what the pointer to void should point to, then allocate space for objects of that type.
Originally Posted by Bjarne Stroustrup (2000-10-14)
I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. «Finding the smallest program that demonstrates the error» is a powerful debugging tool.
Look up a C++ Reference and learn How To Ask Questions The Smart Way
-
08-31-2012
#3
Registered User
Welcome to the forum, Smith283! (void)
-
09-01-2012
#4
Registered User
Thnx laserlight for your reply but i didn’t get it, you need to explain more please as i’m a beginer in C.
And actually the problem is in fetching the value inside ptr[i][j] i.e smith->ptr[i][j] . I have allocated the space for void type (size is 5) and now if i want to write into it say a string(characters), i have to just give a starting address of allocated space(&ptr[0][0]). It will successfully write in the allocated space. But if i want to fetch each character from it using «smith->ptr[i][j]» , it is giving an error «invalid use of void expression».So did you get my actuall question?????
Thnx, hope you help.
-
09-01-2012
#5
Registered User
The compiler complains about this line
Code:
smith->ptr[i] = malloc(sizeof(void) * 5);
You cannot get the size of void. void represents an unknown type and that has no size.
if you want to allocate 5 bytes (as stated in the previous post ) then useCode:
smith->ptr[i] = malloc(sizeof(char) * 5);
because sizeof(char) is guaranteed to be 1.
or simplyCode:
smith->ptr[i] = malloc( 5 );
This loops don’t make any sense to me
Code:
for(i=0;i<4;i++) { for(j=0;j<5;j++) { printf("address of ptr[%d][%d] is %p and the value inside it is %d n",i,j,&smith->ptr[i][j],(int)smith->ptr[i][j]); } } }
It seems that you are trying to print 5 ints but there is only space for 5 uninitialized chars
NOTE:
somehow I have the feeling that you wanted to declare struct me asCode:
struct me { int ** ptr; };
to have a 2 dim array of ints.
Kurt
-
09-01-2012
#6
Registered User
Your mechanic wants to know what model and year of car you will be bringing in for service, later today.
You keep saying «a vehicle».
Your mechanic is not able to use that kind of non-specific information.
-
09-01-2012
#7
Algorithm Dissector
With sizeof(void) you may as well be asking the compiler for space for 5 unicorns, as far as it’s concerned. void has no size.
sizeof(void*) on the other hand is perfectly fine. It’s like saying how many bytes do I need to store the GPS coordinates of those unicorns. The compiler basically doesn’t care what the pointer points to, it just knows that you want the size of a pointer, to something.
Note that you’ll also have an issue with the printf that contains this:
You can index the array of void* pointers with the [i] part, but then at the j part you’re asking it to index into an array of voids after that. Since it doesn’t know how big voids are, that wont work.
You need to change the pointer type at that point in the expression (or earlier) from void* to int* before the last array indexing. It’s too late to cast it to int afterwards.
I suggest breaking it up and storing the smith->ptr[i] part into a separate variable first, then your printf statements will be much easier.My homepage
Advice: Take only as directed — If symptoms persist, please see your debuggerLinus Torvalds: «But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong»
-
09-01-2012
#8
Registered User
One question for all of you, if i comment the following lines as shown in the code below, it would work or not????
Code:
#include<stdio.h> #include<stdlib.h> struct me { void **ptr; }*smith; int main() { int i,j; smith = malloc(sizeof(struct me)); smith->ptr=malloc(sizeof(void *) * 4); for(i=0;i<4;i++) { smith->ptr[i] = malloc(sizeof(void) * 5); } for(i=0;i<4;i++) { printf("address of ptr[%d] is %p and the value inside it is %p n",i,&smith->ptr[i],smith->ptr[i]); } /* for(i=0;i<4;i++) { for(j=0;j<5;j++) { printf("address of ptr[%d][%d] is %p and the value inside it is %d n",i,j,&smith->ptr[i][j],(int)smith->ptr[i][j]); } } */ return 0; }
-
09-01-2012
#9
Registered User
Answer yes or no?? Please……
-
09-01-2012
#10
Algorithm Dissector
We’ve all been telling you that sizeof(void) cannot be used and yet you’ve shown code where you still have exactly that on line 20.
So what do you think?*…
People will stop responding when you stop bothering to pay attention to what they are saying!*Of course that wont «work». It wont compile for the reasons we’ve told you.My homepage
Advice: Take only as directed — If symptoms persist, please see your debuggerLinus Torvalds: «But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong»
-
09-02-2012
#11
Registered User
Extremly sorry mate, i should have told you all in the begining that i’m using GCC compiler (fedora 14, linux).
And iMalc, i think the program in the above lastest post of mine will work fine (without errors). The problem here is not the «sizeof(void)» bt error comes from the printf line that i’ve commented.
And it would allocate the memory for void type succcessfully:-Code:
for(i=0;i<4;i++) { smith->ptr[i] = malloc(sizeof(void) * 5); }
The error «invalid use of void expression» which the compiler is giving is for this line:-
Code:
printf("address of ptr[%d][%d] is %p and the value inside it is %d n",i,j,&smith->ptr[i][j],(int)smith->ptr[i][j]);
If i try to print «sizeof(void)» it wont work, but how it is allocating memory «void» type in this line:-
Code:
smith->ptr[i] = malloc(sizeof(void) * 5);
I need a perfect reason for this.
Also i’ve done writting into void type allocated space, if you people are right then how this is working:-
Code:
#include<stdio.h> #include<stdlib.h> #include<string.h> struct me { void **ptr; }*smith; int main() { int i,j; char buff[5]="hello"; smith = malloc(sizeof(struct me)); smith->ptr=malloc(sizeof(void *) * 4); for(i=0;i<4;i++) { smith->ptr[i] = malloc(sizeof(void) * 5); memset(smith->ptr[i],'',sizeof(void) * 5); } for(i=0;i<4;i++) { printf("address of ptr[%d] is %p and the value inside it is %p n",i,&smith->ptr[i],smith->ptr[i]); } strncpy(smith->ptr[0],buff,5); // or // strcpy(&smith->ptr[0][0],buff); printf("the string is : %sn",smith->ptr[0]); // or // printf("the string is : %sn",&smith->ptr[0][0]); /* for(i=0;i<1;i++) { for(j=0;j<5;j++) { printf("address of ptr[%d][%d] is %p and the value inside it is %c n",i,j,&smith->ptr[i][j],(char )smith->ptr[i][j]); ****Compiler give error on this line not on the sizeof(void)**** } } */ return 0; }
Thnk You
smith
-
09-02-2012
#12
Registered User
Does in linux «void» size is 1byte????
-
09-02-2012
#13
Master Apprentice
The problem here is not the «sizeof(void)» bt error comes from the printf line that i’ve commented.
Like so many newbies who think they know what they are doing you are only looking for confirmation of a self-inflicted misunderstanding.
I need a perfect reason for this.
You’ve been given the reason. You rejected that reason.
You want a «perfect» reason for this that meshes with your poor understanding of C.
Also i’ve done writting into void type allocated space, if you people are right then how this is working:-
It isn’t; it doesn’t.
«GCC» is letting you do this without complaining because an extension relevant to the history of C; the compiler doesn’t care if you use this extension incorrectly by default.
Add «-pedantic» to your command line and the compiler will start complaining.
Soma
-
09-02-2012
#14
Registered User
I have’nt rejected anything, the problem is i’m not getting it
sizeof(void) is invalid to use, i get it.
but would it allocate memory for void type or not in this line???????????????
«smith->ptr[i] = malloc(sizeof(void) * 5);»
-
09-02-2012
#15
Registered User
If «yes» :This is your answer:-
» «GCC» is letting you do this without complaining because an extension relevant to the history of C; the compiler doesn’t care if you use this extension incorrectly by default.
Add «-pedantic» to your command line and the compiler will start complaining. «
if «no» :then your answer is:-
» You’ve been given the reason. You rejected that reason. «
????
????