Функция C, которая вычисляет общий размер аргументов

В настоящее время я пытаюсь вычислить общий размер аргументов, переданных в функцию, в байтах. Теоретически можно просто написать sizeof (x) для каждого аргумента. Однако это огромная трата времени, если кто-то хочет сделать это для множества функций. Я пытаюсь вычислить количество места для аргументов, чтобы я мог выделить нужный объем памяти для их хранения и хранения (для различных функций со смешанными типами).

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

В настоящее время я ' Я нашел три подхода, которые можно было бы изменить, чтобы я мог это сделать. Первый основан на концепциях из подсчета аргументов Лорана Денио . Теоретически я могу использовать макрос для генерации заголовка функции и проделать подобную причудливую работу, чтобы взять количество аргументов и передать их различным макросам, которые обрабатывают КАЖДЫЙ индивидуальный случай, когда есть N аргументов. (См .: Уродливый). По сути, я бы просто использовал псевдонимы для всех имен функций с помощью макроса, а затем использовал sizeof для каждой из них. Проблема в том, что мне нужно создать макрос для КАЖДОЙ длины аргументов, которые я хочу представить. И я действительно не предпочел бы делать 64 (или более) объекта для выполнения одной работы.

Второй подход - попытаться следовать подходу Бена Клемера «лучше вариативного» материала . Я бы не стал использовать весь его подход, но я бы попытался создать структуру, которая представляет сигнатуру arg функции в структуре. Затем я мог бы попытаться получить размер элементов конструкции (или даже самой конструкции, если бы все, что меня заботило, было консервативной оценкой пространства). Здесь есть несколько проблем. Во-первых, он может работать только с C99-совместимыми вещами (все еще проверяю это). Во-вторых, это приводит к созданию дополнительной структуры для каждой реализованной функции. Это не совсем проблема, но все же проблема заключается в том, что его подход к созданию структуры заканчивается теми же именами, что и функция (поэтому вам все равно нужно ссылаться на имена, чтобы использовать их). Хотя я, вероятно, мог бы обойти это.

Третий возможный подход - это рекурсивный макрос, хотя я не уверен, насколько это нравится компиляторам. Теоретически возможно рекурсивно выталкивать элементы из VA_ARGS , вызывая макрос в форме POPPER (arg, ...) POPPER ( VA_ARGS ) + sizeof (arg) . Понятно, что потребуется правило остановки, когда VA_ARG пусто (и что-то, что вас не поймает с плавающим знаком +), но идею вы поняли.

Любой из них. эти вещи позволили бы мне сделать это:

  1. Хорошие, гибкие способы распаковки VA_ARGS из вариационного макроса. Если есть способ проиндексировать его
  2. Хороший пример рекурсивного макроса, на который можно положиться (а также его ограничения в максимальном количестве аргументов, совместимости компилятора, соответствии стандартам и т. Д.).
  3. A способ напрямую получить общий размер всех аргументов с помощью другого типа проверки функций. GCC, похоже, имеет несколько сумасшедших функций для создания вызовов функций для переадресации вызовов, которые могут быть применимы, но они зависят от компилятора, почти не документированы и, похоже, не сообщают размер блока памяти, который они выделяют . Они также сообщают тонны нерелевантной информации.

7
задан Community 23 May 2017 в 12:31
поделиться