Nano Hash - криптовалюты, майнинг, программирование

Приведите все аргументы к типу в вариативном макросе

Я хочу использовать sscanf для синтаксического анализа длинной строки..
Анализируемые данные будут храниться в структуре, все члены которой имеют тип time_t.
К сожалению, нет никакой строки формата для обозначения time_t поэтому я просто приведу все аргументы time_t * к типу unsigned long long *, и поскольку это очень длинная строка с большим количеством аргументов, приведение типов каждого аргумента один за другим только испортит мой экран редактора..

Итак, я создал макрос, чтобы упростить это:

#define typecast(type, ...) (type) __VA_ARGS__

И я вызывал его так:

sscanf(string, PARSE_STRING,
    typecast(unsigned long long *, /* my arguments */));

Я думал, что это расширится до:

sscanf(string, PARSE_STRING,
    (unsigned long long *) /* arg1 */, (unsigned long long *) /* arg2 */, /* and so on */);

Но после проверки с помощью gcc -E я обнаружил, что это расширено до этого:

sscanf(string, PARSE_STRING,
    (unsigned long long *) /* arg1 */, /* arg2 */, /* and so on */));

Как я могу добиться желаемой функциональности расширения с помощью функций с переменным числом аргументов?


  • Вы можете получить вдохновение здесь. 20.11.2014
  • На этот вопрос также есть несколько соответствующих ответов. 20.11.2014
  • Обратите внимание, что time_t обычно является целым числом со знаком. Если вы сканируете, вы должны быть уверены, что тип совместим с time_t — это несколько зависит от платформы. 20.11.2014
  • @JonathanLeffler: я не знал, что time_t был подписан, потому что время равно нулю или положительно, но в любом случае я уверен, что данные, которые я читаю, никогда не будут иметь отрицательных значений. 21.11.2014
  • Классически время 0 равно 1970-01-01 00:00:00 Z (или +00:00). Функция mktime() возвращает (time_t)-1 при ошибке. Для 32-битного типа со знаком (long в более старых 32-битных системах) диапазон представляемых значений времени составляет примерно от 1901-12-13 (0x80000000) до 2038-01-18 (0x7FFFFFFFF). Вот почему вы иногда будете видеть комментарии о кризисе 2038 года; Тогда 32-битный подписанный time_t будет пролонгирован. Большинство систем теперь используют 64-битную версию time_t, чтобы избежать этой проблемы (а также проблемы Y10K и т. д.). 21.11.2014

Ответы:


1

использовать ускорение

#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

#define CAMMA(r, data, i, elem) BOOST_PP_COMMA_IF(i)elem
#define CAST(r, data, elem) (data)elem
#define typecast(type, ...) BOOST_PP_SEQ_FOR_EACH_I(CAMMA, , BOOST_PP_SEQ_TRANSFORM(CAST, type, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))
20.11.2014
  • @AmrAyman boost/preprocessor также можно использовать в C (потому что используется только препроцессор) 21.11.2014

  • 2

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

    #define typecast4(type, a1, a2, a3, a4, ...) ((type)a1), ((type)a2), ((type)a3), ((type)a4)
    #define typecast(type, ...) typecast4(type, __VA_ARGS__, NULL, NULL, NULL, NULL)
    

    Это конкретное решение всегда генерирует 4 аргумента. Обратите внимание, что в вашем случае это не имеет значения, потому что scanf принимает и безопасно игнорирует любые аргументы за пределами введенного формата. Итак, компилируется следующий код:

    int main() {
      time_t x,y;
      scanf("%lld, %lld", typecast(long long *, &x, &y));
      ...
    }
    

    Тем не менее, меня беспокоит актерский состав с time_t * по long long *. Нигде не написано, что time_t должно быть представлено long long. Если он представлен int на какой-либо платформе, предыдущий код будет ошибочным. Правильный способ сканирования ваших значений будет выглядеть примерно так:

    int main() {
      time_t x,y;
      long long lx, ly;
      scanf("%lld, %lld", &lx, &ly);
      x = lx;
      y = ly;
      ...
    }
    

    что более правильно и не требует никакого вариативного макроса.

    20.11.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..