В настоящее время я пытаюсь вычислить общий размер аргументов, переданных в функцию, в байтах. Теоретически можно просто написать sizeof (x)
для каждого аргумента. Однако это огромная трата времени, если кто-то хочет сделать это для множества функций. Я пытаюсь вычислить количество места для аргументов, чтобы я мог выделить нужный объем памяти для их хранения и хранения (для различных функций со смешанными типами).
Я ищу составить выражение, которое может определять размер всех аргументов невариадной функции, независимо от их имен и независимо от того, сколько их (в разумных пределах, на данный момент я могу поддерживать только около 64 аргументов). Это может быть функция, макрос препроцессора, я не отношусь к реализации. Мне также было бы интересно обрабатывать вариативные функции, но я почти уверен, что это невозможно, потому что к тому времени, когда вы перейдете к вариативной функции, вы потеряете всю информацию о типах данных.
В настоящее время я ' Я нашел три подхода, которые можно было бы изменить, чтобы я мог это сделать. Первый основан на концепциях из подсчета аргументов Лорана Денио . Теоретически я могу использовать макрос для генерации заголовка функции и проделать подобную причудливую работу, чтобы взять количество аргументов и передать их различным макросам, которые обрабатывают КАЖДЫЙ индивидуальный случай, когда есть N аргументов. (См .: Уродливый). По сути, я бы просто использовал псевдонимы для всех имен функций с помощью макроса, а затем использовал sizeof для каждой из них. Проблема в том, что мне нужно создать макрос для КАЖДОЙ длины аргументов, которые я хочу представить. И я действительно не предпочел бы делать 64 (или более) объекта для выполнения одной работы.
Второй подход - попытаться следовать подходу Бена Клемера «лучше вариативного» материала . Я бы не стал использовать весь его подход, но я бы попытался создать структуру, которая представляет сигнатуру arg функции в структуре. Затем я мог бы попытаться получить размер элементов конструкции (или даже самой конструкции, если бы все, что меня заботило, было консервативной оценкой пространства). Здесь есть несколько проблем. Во-первых, он может работать только с C99-совместимыми вещами (все еще проверяю это). Во-вторых, это приводит к созданию дополнительной структуры для каждой реализованной функции. Это не совсем проблема, но все же проблема заключается в том, что его подход к созданию структуры заканчивается теми же именами, что и функция (поэтому вам все равно нужно ссылаться на имена, чтобы использовать их). Хотя я, вероятно, мог бы обойти это.
Третий возможный подход - это рекурсивный макрос, хотя я не уверен, насколько это нравится компиляторам. Теоретически возможно рекурсивно выталкивать элементы из VA_ARGS , вызывая макрос в форме POPPER (arg, ...) POPPER ( VA_ARGS ) + sizeof (arg)
. Понятно, что потребуется правило остановки, когда VA_ARG пусто (и что-то, что вас не поймает с плавающим знаком +), но идею вы поняли.
Любой из них. эти вещи позволили бы мне сделать это: