LINUX.ORG.RU

c define macro с результатом выполнения функции

 ,


0

1

Хочется в C использовать switch для строк и пришла идея:
объявить макрос с хэш функцией, которая выполнится во время компиляции, а результат подставить в макрос. И уже затем пользоваться этим челочисленным результатом в switch.
Можно ли что-то проще сделать для получения switch по строкам?



Последнее исправление: cetjs2 (всего исправлений: 1)

покажи как хочешь, чотт я не догнал что с чем ты там хотишь.

типа такого?

void call( char *str )
{
    switch( socme_hash(str) ) {
       case HASH("123"):{}
       case HASH("456"):{}
       case HASH("789"):{}
       case HASH("901"):{}
    }
}
anonymous
()
Ответ на: комментарий от anonymous

Да, вроде этого, только

#define 123 HASH("123")
#define 456 HASH("456")

при определенной функции, что бы HASH выполнялась на этапе компиляции с подстановкой результата в макрос.

ykroop
() автор топика
Последнее исправление: ykroop (всего исправлений: 1)

В C не получится. В C++ можно на шаблонах и constexpr.

anonymous
()
Ответ на: комментарий от ykroop

Ничё не понял, а зачем это надо?

HASH

Какой хеш?

anonymous
()

Лучше не вычислять никаких хэшей, а воспользоваться генератором кода для свича по строкам. re2c, например.

Sorcerer ★★★★★
()

На всякий случай напомню, что хеш не является уникальным идентификатором.

arturpub ★★
()

Присоединяюсь к предыдущему оратору. Твой "хеш" ничего путного не даст. Лучше уж напиши обертку, которая будет CASE("x") переделывать в strcmp(str, "x") == 0 и не на case'ах, а на else if'ах.

anonymous
()

Препроцессор работает только в один проход, так что пользуй функции с кейсами.

Bfgeshka ★★★★★
()
Ответ на: комментарий от kirk_johnson

Ты можешь показать что-то, что умеет это делать и где строки не «ущербны»? Удиви меня.

anonymous
()
Ответ на: комментарий от kirk_johnson

Не делай так.

Как не нужно делать?

Строки в C достаточно ущербны, с этим придется смириться.

Смириться с чем и почему c-строки ущербны?

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Как не нужно делать?

Не нужно пытаться case'ом обрабатывать строки. Они так не работают.

Смириться с чем и почему c-строки ущербны?

Потому что строки - массивы с соглашением о нулевом байте в конце. Со всеми вытекающими.

kirk_johnson ★☆
()
Ответ на: комментарий от kirk_johnson

Не нужно пытаться case'ом обрабатывать строки. Они так не работают.

Потому ТС и завел речь о хеше в компайл-тайм.

Потому что строки - массивы с соглашением о нулевом байте в конце. Со всеми вытекающими.

Ну и что там вытекает? Что плохого в таком формате строки?

andreyu ★★★★★
()
Ответ на: комментарий от kirk_johnson

Отсутствие операции сравнения в языке :)

А кроме бреда вы способны что-либо еще сказать?

andreyu ★★★★★
()
Ответ на: комментарий от kirk_johnson

Отсутствие операции сравнения в языке :)

А где она есть? Она везде на уровне рантайма.

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

Свич по строкам не имеет смысла. Он ничем не будет отличаться от тонны ифов, что является убогой реализация обычного поиска из одного цикла. Это убожество и не нужно.

anonymous
()

Я могу кодогенератор скостылить. Кстати, если строки умещаются 8 бит без учета нуль-терминирующего символа, и работать под 64-бит, можно очень эффективно это разрулить обычным свитчем через строку преборазованную в uint64_t без всяких хэш-функций. А если 32-бит то только 4 бит эффективно получится (хотя оно и с uint64_t скомпилится, но не так круто будет)

SZT ★★★★★
()
Ответ на: комментарий от SZT

А это кстати возможное решение, строки действительно небольшие, 2-6 символов только в ascii. Спасибо за подсказку.

ykroop
() автор топика
Последнее исправление: ykroop (всего исправлений: 2)
Ответ на: комментарий от SZT

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

можно ещё извратиться с merge_const_string (так оно кажись назыается) и поддерживать уникальность строк на уровне рантайм. Тогда

swicth(collectedString) {
  case "hello": foo(); break;
  case "word": bar(); break;
}
вызывает некоторую ругань компилятора, но работоспособно

хотя это и извращение :-) Вряд-ли у вас и ТС в приложениях есть коллекции строк порядка 2^12 чтобы поиск в дереве/хеш таблице стал узким местом.

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.