- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
static enum rc (*request_functions[])(void) = {
ko,
koko,
kokoko,
illegal_request
};
static inline enum rc illegal_request(void) { return ILLEGAL_REQUEST; }
reply.rc = request_functions[cmd.opcode < NKEYS(request_functions) ? cmd.opcode : ILLEGAL_REQUEST]();
Анонимус 12.11.2014 13:54 # 0
Но вообще молодцы что возвращают ILLEGAL_REQUEST а не выполняют какой-то случайный код на который там дальше в памяти указатель случайно оказался
Dummy00001 12.11.2014 14:09 # 0
лэйбл "poor man's" неприменим. потому что в С нет другуго способа. только свитч/кейс и таблица функций. на практике, таблица функций 20-30% быстрее.
Анонимус 12.11.2014 14:17 # 0
Для сишников наверное годно собрать в памяти указатели на функции и по ним скакать
bormand 12.11.2014 14:37 # 0
Ты так говоришь, как-будто питонисты не собирают функции в мап, чтобы по ним скакать.
Анонимус 12.11.2014 14:39 # 0
bormand 12.11.2014 14:40 # +1
Анонимус 12.11.2014 14:46 # +1
В конце концов можно сделать так
bormand 12.11.2014 14:49 # 0
Чтобы из разных мест понарегать туда 100500 функций-обработчиков. Может быть даже в рантайме их добавлять при подгрузке каких-нибудь плагинов или конфигов...
А ваш вариант, простите, вообще какое-то говно. Ибо позволяет дергать любые методы MessageServer'а - и "приватные" и унаследованные...
Анонимус 12.11.2014 14:51 # 0
для кода сверху
bormand 12.11.2014 14:59 # 0
Анонимус 12.11.2014 15:03 # 0
ну ок, я напишу так:
всё еще джсвей?
bormand 12.11.2014 15:07 # 0
1) лишние функции/свойства недоступны (что спасёт от уязвимостей, если в accept прилетают внешние данные)
2) класс используется по назначению и содержит мап, а не используетя в качестве оного
3) можно прикрутить декоратор для удобной регистрации (см. ниже)
4) можно получить список доступных обработчиков (что при использовании класса как мапа превращается в говнище)
5) у этого объекта могут быть нормальные методы, которые не смешиваются в кучу с обработчиками
P.S. Я надеюсь,что install_new_handler не написан через setattr? :)
Анонимус 13.11.2014 09:25 # 0
Ну или хотябы манглит методы добавляя пару подчеркиваний. На самом деле даже одного подчеркивания бы хватило, потому что уже тогда они не засирали бы публичный контракт. А в непубличном можно гусе что угодно делать
bormand 12.11.2014 15:03 # 0
roman-kashitsyn 12.11.2014 15:36 # +1
Dummy00001 12.11.2014 15:05 # +2
... называется энтерпрайз!!!
bormand 12.11.2014 15:13 # 0
При старте демон сканил папку, искал в ней модули и загружал их. Каждый модуль регал один или несколько хендлеров в глобальную мапу.
При запросе демон искал хендлер в мапе и исполнял его.
Говно, как считаете?
Xom94ok 12.11.2014 23:54 # +2
bormand 13.11.2014 00:01 # +1
Да там и кода то ненамного больше. Строчек 50-100 от силы в main'е. Остальное в тех самых модулях.
P.S. Сейчас бы я поюзал flask и не ебал бы мозг с самодельным RPC. А тогда бакой был ;(
bormand 13.11.2014 00:03 # +1
Блин, а ведь выглядит как обращение. Походу, я лох и обосрался с пунктуацией. Сорри :)
Dummy00001 12.11.2014 15:13 # 0
Оно и на современных языках часто оказывается нужно. Например, С++ vs Object Pascal, диспатч через С++ виртуальный метод был на порядок быстрее чем в Дельфе, почему приходилось в узких местах в ручную таблицы указателей на методы делать, с диспатчем не сильно отличающимся от того как в ГК.
Dummy00001 12.11.2014 14:05 # 0
bormand 12.11.2014 14:42 # 0
Ну хотя бы тайпдеф то можно было сделать... Чтобы enum не писать каждый раз, и была возможность перепилить на uint32_t...
kipar 12.11.2014 15:15 # 0
Например у атмела:
видимо считают что так удобнее, сразу видно где у нас запись, а где енум. Других объяснений не вижу.
codemonkey 12.11.2014 16:11 # 0
Dummy00001 12.11.2014 16:27 # 0
но делать сам тип кода возврата enum'ом это совсем другое.
с другой стороны, у "сраных дефайнов" есть Н-ое количество преимуществ, в оссобенности для больших проектов. например можно проверить определен ли уже код ошибки или нет. в добавок, синтакс не требует этих грёбаных запятых, которые при переливании кодов из одного языка в другой надо выкидывать. распилить кучу дефайнов я могу и на шелле - но что бы распилить кучу enum'ов как минимум перл желателен.
codemonkey 12.11.2014 16:35 # 0
Обоснуйте.
Dummy00001 12.11.2014 16:46 # +1
это работает только на простых проектах, на которых внутренний rc это просто overdesign.
на больших проектах это значит что объявление энума будет жутким хаком, потому что должно содержать коды с большого количества файлов/модулей/подмодулей. что в принципе сделать одним централизованым определением часто просто невозможно. если даже какими инклюдами извращатся, то либо определение будет зависеть от порядка инклюдов, или просто нельзя полагатся на численное значение кода. (ну и двоичная совместимость с либами в ж вылетает.) либо надо все значения прописывать в ручную - и в этот момент ты оказываешься в том же самом корыте что и со сраными дефайнами.
codemonkey 12.11.2014 17:05 # 0
TarasB 12.11.2014 14:07 # 0
TarasB 12.11.2014 14:14 # +1
ёбаная ритчи уебанское это опять объявление сука
TarasB 12.11.2014 14:15 # +1
Dummy00001 12.11.2014 15:09 # 0
сишные enum/struct/union (захардкоженые в язык) это прародители современных нэймспэйсов (юзер дефайнабл).
на практике весьмя удобно (хотя и очень ограничено), потому что нет конфликта между именами переменных и именами типов.
Анонимус 12.11.2014 14:16 # 0
enum[ТИП]{}
[ТИП] в данном случае есть указатель на функцию которая ничего не принимает (void)
gumbert 13.11.2014 13:52 # +1
codemonkey 13.11.2014 18:46 # 0
Не совсем. В энуме опкодов его нет.
Кстати, ваш код идентичен ГК если раз-inline-ить функцию illegal_request.
bormand 13.11.2014 18:48 # 0
Но, тем не менее, он равен числу опкодов + 1. И вот это уже пиздец...
В енуме rc лежит такое значение, которое равно количеству элементов +1 в енуме опкодов.
Вариант gumbert'а лучше, т.к. не вносит неявной связи между двумя енумами.
codemonkey 14.11.2014 01:29 # +1