Изврат с шаблонами. Часть 2 (последняя)

Dima T
Дата: 13.03.2015 18:45:15
Продолжение той же задачи, но ситуация обратная: все работает, но вопрос не накосячил ли я с приведениями типов?

Суть такая: передаю в другой трэд: или структуру, или указатель на нее, или int, и функцию для обработки, которая потом вызывается. Функция должна быть объявлена так:
void my_worker(my_type_t& x)


Изврашаюсь чтобы не писать везде void* в параметрах, а потом приводить. Вобщем чтобы спрятать порнографию поглубже, т.е. в set_value() и izvrat().

Получилось вот что (упростил как смог):
typedef void (*worker_t) (int*& x);

int* value;

template< typename T >
void set_value(T& v)
{
	if(sizeof(T) == sizeof(int*)) {
		*(T*)&value = v;
	} else {
		value = (int*)malloc(sizeof(T));
		if(value) memcpy(value, &v, sizeof(T));
	}
}

template< typename T >
void izvrat(T worker_func, bool is_ptr)
{
	worker_t worker = (worker_t) worker_func;
	if(is_ptr) {
		worker((int *&)*value);
		free(value);
	} else {
		worker(value);
	}
}

void print_int(int& x) {
	printf("%d\n", x);
}

void print_double(double& x) {
	printf("%f\n", x);
}

void  main(){
	int i = 1;
	set_value(i);
	izvrat(print_int, false);
	double j = 2;
	set_value(j);
	izvrat(print_double, true);
}


Понятно что если левую функцию подсуну, то компилятор не заметит, но оно сразу вылезет при отладке. Интересует не вылезет ли чего на другом компиляторе.
Leonid Kudryavtsev
Дата: 13.03.2015 18:50:04
Dima T
вопрос не накосячил ли я с приведениями типов?

в коде столько косяков и очепяток, что искать среди них "с приведениями типов" как-то даже лениво )))

совершенно не понятно, почему вместо употребимого (void *) используется (int *). Лично мне, это взрывает глаза и мозг

Ну и Анатолий был фактически провидцем:
Anatoly Moskovsky
Dima T,

Я надеюсь в реальном коде нет присвоения из функции в глобальную переменную?

совместно с
Dima T
передаю в другой трэд

это ставит в ступор и повергает в шок
Leonid Kudryavtsev
Дата: 13.03.2015 18:57:02
Dima T
Интересует не вылезет ли чего на другом компиляторе.

IMHO не должно. Совершенно нормальное C-ное приведение типов через указатель.

Для меня через чур сложно, из за reference. Но в целом, раз работает, значит корректно.
Dima T
Дата: 13.03.2015 19:02:04
Leonid Kudryavtsev
в коде столько косяков и очепяток, что искать среди них "с приведениями типов" как-то даже лениво )))

Просто покажи где и почему, разжевывать не надо, сам погуглю

Leonid Kudryavtsev
совершенно не понятно, почему вместо употребимого (void *) используется (int *). Лично мне, это взрывает глаза и мозг

потому что нет просто void, только void*, никак не компилировалось пока на int не заменил. Подскажешь как - верну обратно. Мне тоже тут int не нравится.

Leonid Kudryavtsev
Ну и Анатолий был фактически провидцем:
Anatoly Moskovsky
Dima T,

Я надеюсь в реальном коде нет присвоения из функции в глобальную переменную?

совместно с
Dima T
передаю в другой трэд

это ставит в ступор и повергает в шок

Глобальная переменая для наглядности (в реале std::queue<int*>), чтобы пример кода был рабочий и короткий. В реальном коде ее нет. Если я вывалю сюда всю поделку ее вообще никто читать не станет.
Leonid Kudryavtsev
Дата: 13.03.2015 19:06:16
Dima T
Просто покажи где и почему, разжевывать не надо, сам погуглю

Очепятки. Надеюсь, в рабочем коде их нет. (например is_ptr, который проверяется, но нигде не присваивается и т.д.)

Dima T
Leonid Kudryavtsev
совершенно не понятно, почему вместо употребимого (void *) используется (int *). Лично мне, это взрывает глаза и мозг

потому что нет просто void, только void*, никак не компилировалось пока на int не заменил. Подскажешь как - верну обратно. Мне тоже тут int не нравится.

А какая компилятору разница?

Если я правильно мысль уловил. Пошел поэкспериментирую. Но будет без reference, я их плохо знаю и не люблю ))).
Leonid Kudryavtsev
Дата: 13.03.2015 19:08:22
Сорри, ступил. Is_ptr ты в качестве параметра кидаешь (не понятно зачем, т.к. по sizeof ты же все равно знаешь, поместилось в указатель или нет).
Leonid Kudryavtsev
Дата: 13.03.2015 19:25:01
Да... еще очень веселая ошибка: error C2664 в MS VC

1) с (int*) код перестает быть универсальным. Кроме int, ничего другого (например bool) передать через указатель не получится. То есть, не понятно, нахрена козе баян.
2) зачем везде reference ? почему не использовать вместо этого ООП убожества нормальные C-ные ссылки?
Dima T
Дата: 13.03.2015 19:51:48
Leonid Kudryavtsev
Сорри, ступил. Is_ptr ты в качестве параметра кидаешь (не понятно зачем, т.к. по sizeof ты же все равно знаешь, поместилось в указатель или нет).

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

Leonid Kudryavtsev
Да... еще очень веселая ошибка: error C2664 в MS VC

1) с (int*) код перестает быть универсальным. Кроме int, ничего другого (например bool) передать через указатель не получится. То есть, не понятно, нахрена козе баян.
2) зачем везде reference ? почему не использовать вместо этого ООП убожества нормальные C-ные ссылки?

MS VC 2008 Express никаких ошибок. на *(T*)& есть warning C4739: reference to variable 'value' exceeds its storage space, это понтно. Почему и спрашивал что не сглючит. У тебя какой MS VC? Текст ошибки желательно.

1. Как уже написал: указатели, структуры или индексы массивов. 4 байта во всех случаях. Я же для себя, bool на int можно заменить, все равно выравнивание до 4 байт.
2. Не совсем понял о чем речь. Стремился вот к чему:

Обычный подход: если одно и тоже написано дважды, то на третий раз надо обобщать. Дважды уже написано, надо третий, вот и занялся. Создание потока, эвенты и критические секции для межпотоковой синхронизации, цикл с ожиданием, куча хрени которую надо спрятать.

Убил день вместо копипаста за полчаса, но не жалею. В итоге:
#include "izvrat.h"

void int_worker(int& task)
{
	printf("work %d\n", task);
}

int main(int argc, char* argv[])
{
	my_worker_t mw = {0};
	thread_worker_create(mw, int_worker);
	for(int i = 1; i < 10; i++) {
		worker_add(mw, i);
	}
	thread_worker_stop(mw);
}

Красота :)
Leonid Kudryavtsev
Дата: 13.03.2015 20:12:27
Dima T
Красота :)

Мне указывать * при обращении к данным, не напрягает
Т.ч. вообще не вижу смысла использовать reference и получать кучу дебильных ошибок и не очевидный код. IMHO
Dima T
Дата: 13.03.2015 20:24:45
Dima T
У тебя какой MS VC? Текст ошибки желательно.

Текст нагуглил, видно компилятор MS VC поумнел и начал пресекать такие извраты. Печалька вообще пофиг, лет на 10 хватит, недавно с VC6 перешел. Затестил в линуксе - собирается.