Вопрос

Как сделать приведенную ниже функцию универсальной для uint8_t, uint16_t, uint32_t, int8_t, int16_t, int32_t и float_t?

Как видите, я не люблю повторять одну и ту же логику в каждом случае.Единственная разница в каждом случае - это кастинг.

В идеале мне хотелось бы иметь решение, соответствующее стандарту C и, следовательно, переносимое.Любые идеи приветствуются.

Спасибо.

родовое слово
Это было полезно?

Решение

Ну, вы можете извлечь приведенные типы:

Genracodicetagpre

Или, если различные типы образуют непрерывный диапазон значений от 0, вы даже можете создать два массива указателей на функции и сделать:

Genracodicetagpre

Примечания:

  • Вам все равно придется написать по две функции для каждого типа, хотя при желании они легко сгенерируются макросами.
  • Вряд ли стоит использовать этот небольшой код.
  • Я выбрал int64_t, поскольку он может представлять все значения всех используемых вами целочисленных типов, поэтому преобразования в int64_t никогда не отбрасывают информацию и никогда не изменяют результат сравнения относительно выполнения того же сравнения в тип источника. Но если вы также хотите охватить uint64_t, вы не можете использовать один и тот же тип для всего, поскольку не существует целочисленного типа, который мог бы представлять все значения всех целочисленных типов. Вам также понадобится отдельная функция testLimitsf для float, возможно, с использованием long double в качестве общего типа для обеспечения гибкости в будущем.
  • [Edit: я только что понял, предполагая, что IEEE-754, double действительно может точно представлять все значения всех используемых вами типов. Таким образом, с небольшим ограничением переносимости, вы можете использовать testLimitsf для всего и работать с двойными]
  • Вы уверены, что перед сравнением стоит преобразовать (например) в uint8_t? Либо значение находится в диапазоне для кода uint8_t, и в этом случае вам не нужно преобразовывать, вы можете просто провести сравнение. В противном случае значение не входит в диапазон, и в этом случае уменьшение по модулю делает сравнение немного бессмысленным, за исключением особых случаев 0 и -1. Так что, возможно, оно того стоит, если что-то, о чем вы не сказали, делает это так, но мне это кажется подозрительным.
  • В комментарии вы сказали: «Я пытаюсь сделать эту функцию более эффективной». Это может пойти против этого. Логически возможно встроить код testLimits, а также вызовы функций приведения в код switch, но я бы не стал на это рассчитывать.

Другие советы

Нет простого способа выполнить такое обобщенное программирование на языке C.Если вы беспокоитесь о техническом обслуживании, это может быть редким случаем, когда подходит макрос.

Почему бы не использовать макрос?

родовое слово

В следующей редакции стандарта (C1x) будет добавлена поддержка общих выражений типа (пример из Википедии):

родовое слово

gcc имеет предварительную поддержку C1x.Я думаю, что _Generic еще не поддерживается, но помните об этом на будущее.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top