Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Программирование Новый топик    Ответить
 Работа с void указателями в С  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Есть структура

typedef struct 
{  
    void *l_var;      
    void *r_var;    
}EXPR;

EXPR expr;


Инициализирую
expr.l_var = &motor_rt_params[0].position;
expr.r_var = &motor_rt_params[1].position;


Но теперь если я хочу выполнить операцию
result = *(expr.l_var) – *( expr.r_var);


я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Нужно явно привести к типу
result = *((int32_t *) expr.l_var) - *((int32_t *)expr.r_var);


Но не все переменные 32 бита, есть 16, 8.
Как мне универсально преобразовать к нужному типу?
12 май 19, 12:32    [21882704]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
alex55555
Member

Откуда:
Сообщений: 2129
jenya7
Но теперь если я хочу выполнить операцию
result = *(expr.l_var) – *( expr.r_var);


я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Напиши подробно, зачем ты использовал каждый знак в данной операции.
12 май 19, 12:55    [21882715]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
kolobok0
Member

Откуда:
Сообщений: 1951
jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)
12 май 19, 12:58    [21882716]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
alex55555
jenya7
Но теперь если я хочу выполнить операцию
result = *(expr.l_var) – *( expr.r_var);


я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Напиши подробно, зачем ты использовал каждый знак в данной операции.

Допустим есть генерик
void SCRIPT_Process(void *l_var, void *r_var, uint32_t oper)
{
    int32_t res;
     
    switch (oper)
    {
        case OP_PLUS: 
            res = *((int32_t *) l_var) + *((int32_t *)r_var);
        break;
        case OP_MINUS: 
            res = *((int32_t *) l_var) - *((int32_t *)r_var);
        break; 
    }
}

Как мне заране знать в какой тип преобразовать?
12 май 19, 13:06    [21882717]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
kolobok0
jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)

юнион не будет работать.
12 май 19, 13:09    [21882718]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
jenya7
kolobok0
jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)

юнион не будет работать.

опять таки - где я решаю в какого типа сохранить указатель?
12 май 19, 13:11    [21882719]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 48132
jenya7
Как мне заране знать в какой тип преобразовать?

Никак, обломись.
12 май 19, 13:54    [21882741]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С.  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6269
Только в С++ можно такое сделать.


Либо шаблонами, либо пользовательскими операторами.
12 май 19, 14:00    [21882743]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
Dima T
Member

Откуда:
Сообщений: 13915
jenya7
Как мне заране знать в какой тип преобразовать?

Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.
12 май 19, 19:09    [21882864]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
kolobok0
Member

Откуда:
Сообщений: 1951
jenya7
...юнион не будет работать.


т.е. приводить указатель к нужному типу через юнион - не получиться? кхм...
ну что я могу сказать - это из разряда = а мужики и не знали... Картинка с другого сайта.


удачи вам, она вам потребуется
(круглый)
12 май 19, 22:10    [21882905]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Dima T
jenya7
Как мне заране знать в какой тип преобразовать?

Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.

тогда такой вопрос
int a, b, c;
c = a + b;

это компилируется в машинный код. как конвейер формирующий команду знает с каким типом оперировать? есть отдельная команда сложения для каждого типа?
13 май 19, 09:04    [21883001]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
Dima T
Member

Откуда:
Сообщений: 13915
jenya7
есть отдельная команда сложения для каждого типа?

Есть. Во время компиляции выбирается соответствующая команда.
13 май 19, 09:12    [21883012]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34486
Есть структура

typedef struct 
{  
    void *l_var;      
    void *r_var;    
}EXPR;

EXPR expr;


Инициализирую
expr.l_var = &motor_rt_params[0].position;
expr.r_var = &motor_rt_params[1].position;


Но теперь если я хочу выполнить операцию
result = *(expr.l_var) – *( expr.r_var);


я получаю исключение
Error[Pe041]: expression must have arithmetic or pointer type

Это не исключение. Это ошибка компиляции.

Нужно явно привести к типу
result = *((int32_t *) expr.l_var) - *((int32_t *)expr.r_var);


Нужно.


Но не все переменные 32 бита, есть 16, 8.
Как мне универсально преобразовать к нужному типу?

Хранить десигнатор хранимого типа, делать по нему switch/if и делать в каждой ветке нужное приведение типа.

Ещё совет -- сначала учить язык программирования, потом пытаться на нём что-то писать.
14 май 19, 12:52    [21884309]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34486
kolobok0
jenya7,

union с разными типами заюзать не судьба или не нравится?

(круглый)


С union проблема будет такая же.
14 май 19, 12:52    [21884312]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34486
jenya7
Dima T
пропущено...

Никак. Указатель это просто адрес в памяти, а тип указателя - как трактовать память по этому адресу (сколько байт и т.д.)
Т.е. из void * никак не восстановить исходный тип. Убирай void * или добавляй данные об исходном типе.

тогда такой вопрос
int a, b, c;
c = a + b;

это компилируется в машинный код. как конвейер формирующий команду знает с каким типом оперировать? есть отдельная команда сложения для каждого типа?



Да, есть.

Конвеер не знает, и не должен. Компилятор знает типы переменных, обрабатывает их, и должным образом генерирует машинный код, где для реализации операций над разными типами используются соответствующие операции и типу операндов машинные комманды.
14 май 19, 12:55    [21884313]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
kolobok0
Member

Откуда:
Сообщений: 1951
MasterZiv
...С union проблема будет такая же.


TC не хочется преобразовывать к указателям разных типов, насколько я понимаешь.
если заюзать юнион - можно тупо обращаться к нужным типам указателя, без приведение к нужному типу.
в чём проблема то?

Если хочется аля полиморфизм - то можно передав переменную в нужным типом, заюзать её в качестве указания нужного типа. Тогда вообще всё кашерно получается.

это собственно очевидные вещи. Картинка с другого сайта.

(круглый)
14 май 19, 13:08    [21884328]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34486
kolobok0
MasterZiv
...С union проблема будет такая же.


TC не хочется преобразовывать к указателям разных типов, насколько я понимаешь.
если заюзать юнион - можно тупо обращаться к нужным типам указателя, без приведение к нужному типу.
в чём проблема то?



Так десигнатор всё равно надо делать, и ветвление по него.
14 май 19, 20:32    [21884768]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6269
А чего эта тема переехала в "программирование" ???

Я может ВБА учил всю жизь, мне ваши укаказатели не в дугу!
14 май 19, 23:12    [21884842]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
kolobok0
Member

Откуда:
Сообщений: 1951
MasterZiv
...Так десигнатор всё равно надо делать, и ветвление по него.


и хде тут десигнатор+ветвление?

typedef union _uPoint
{
	void* vv;
	uint32_t* u32v;
	uint16_t* u16v;
	uint8_t* u8v;
} uPoint;
//
typedef struct 
{
	uPoint l;
	uPoint r;
} EXPR;

void subbFoo(uPoint lv, uPoint rv, uint32_t& rData)
{
	rData = *lv.u32v - *rv.u32v;
}

void subbFoo(uPoint lv, uPoint rv, uint16_t& rData)
{
	rData = *lv.u16v - *rv.u16v;
}

void subbFoo(uPoint lv, uPoint rv, uint8_t& rData)
{
	rData = *lv.u8v - *rv.u8v;
}


юзанье типо

	expr.l.vv = &motor_rt_params[0].position;
	expr.r.vv = &motor_rt_params[1].position;

	uint32_t u32Data = 0;
	uint16_t u16Data = 0;
	uint8_t u8Data = 0;

	subbFoo(expr.l, expr.r, u32Data);
	subbFoo(expr.l, expr.r, u16Data);
	subbFoo(expr.l, expr.r, u8Data);


ик?
15 май 19, 10:40    [21885048]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
jenya7
Member

Откуда:
Сообщений: 1159
kolobok0
MasterZiv
...Так десигнатор всё равно надо делать, и ветвление по него.


юзанье типо

	expr.l.vv = &motor_rt_params[0].position;
	expr.r.vv = &motor_rt_params[1].position;

	uint32_t u32Data = 0;
	uint16_t u16Data = 0;
	uint8_t u8Data = 0;

	subbFoo(expr.l, expr.r, u32Data);
	subbFoo(expr.l, expr.r, u16Data);
	subbFoo(expr.l, expr.r, u8Data);


ик?

во первых третий аргумент rData где то надо хранить. во вторых - *lv.u32v - *rv.u16v; не судьба? значит rData нужно хранить для lv и rv.
а если выражение усложниться var1-var2 > var3 - rData нужно хранить и для var3. отжирается куча места.
15 май 19, 12:39    [21885168]     Ответить | Цитировать Сообщить модератору
 Re: Работа с void указателями в С  [new]
kolobok0
Member

Откуда:
Сообщений: 1951
jenya7
...во первых третий аргумент rData где то надо хранить. во вторых ...


третий аргумент надо хранить там, где Вы и храните Ваш result

result = *(expr.l_var)*( expr.r_var);



во вторых....дальше полёт мысли я простите потерял....

в третьих - выше я дал не решение а рыбу, показав что это возможно. код не претендует на красоту или лаконичность. можно дрейфить как в одну так и в другую сторону.

удачи вам, она вам потребуется
(круглый)
15 май 19, 15:05    [21885385]     Ответить | Цитировать Сообщить модератору
Все форумы / Программирование Ответить