переменная функция - как обеспечить корректную передачу параметров - PullRequest
3 голосов
/ 26 июля 2011

Есть ли способ (встроенный или кодовый шаблон), чтобы гарантировать, что функции с переменными числами передается правильное количество параметров? (Это будет включено как часть API, я могу проверить свой внутренний код.)

Я рассматривал требование, чтобы Магическое число UN32 было последним переданным аргументом, и проверим его на валидность в функции с переменными числами. У кого-нибудь есть мысли по этому поводу?

Ответы [ 6 ]

4 голосов
/ 26 июля 2011

va_* макросы просто извлекают переменные из локального стека, поэтому вы должны доверять пользователю. я думаю, что передача кортежа массива / размера может быть более безопасной.

3 голосов
/ 26 июля 2011

Вы можете использовать макрос PP_NARG , чтобы добавить счетчик полуавтоматически.

int myfunc (int count, ...);
#define MYFUNC(...) myfunc(PP_NARG(__VA_ARGS__), __VA_ARGS__)

MYFUNC(a,b,c,d);
MYFUNC(a,b,c,d,e,f,g);

gcc -E производит:

int myfunc (int count, ...);

myfunc(4, a,b,c,d);
myfunc(7, a,b,c,d,e,f,g);
3 голосов
/ 26 июля 2011

В C или C ++ нет определенного способа гарантировать, что правильное количество аргументов было передано в функцию с переменным числом аргументов. Даже требование подписи не гарантированно работает, так как это может конфликтовать со значением действительного аргумента. Вам, вероятно, будет намного лучше передать вектор <>, так как полученное количество элементов является точным.

2 голосов
/ 26 июля 2011

Не могли бы вы использовать функцию вариативного шаблона C ++ 0x, примененную к функции? Это сгенерирует функцию vararg, которая является типобезопасной.

См. Эту ссылку с его безопасной реализацией printf с использованием шаблонной функции с переменным числом

http://www2.research.att.com/~bs/C++0xFAQ.html#variadic-templates

1 голос
/ 26 июля 2011

Нет.Невозможно.

Variadic нарушает безопасность типов способом, который невозможно исправить.

Если вы хотите вернуть безопасность типов, рассмотрите возможность разбиения переменной функции на несколько типов-безопасных функций-членов класса [small], который содержит общее состояние между их вызовами.

Это всегда возможно, даже если несколько вызовов могут выглядеть неловко по сравнению с одним вариативным вызовом.

Возможно, именно общее состояние вы и хотели использовать в первую очередь для функции вариации.

В качестве примера возьмем iostream vs printf.

1 голос
/ 26 июля 2011

Это зависит от того, что вы подразумеваете под «убедитесь, что в функцию с переменными числами передано правильное количество параметров» ...

Передача магического числа UN32 в качестве последнего аргумента позволит вам определить, где находится списокАргументы заканчиваются, поэтому их общее количество.Итак, подсчитав, сколько аргументов вы нашли до UN32, вы знаете, сколько аргументов у вас есть, и ваша функция должна знать, достаточно ли этого.Не знаю, можно ли вам определить это во время выполнения (это может быть слишком поздно) ...

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

...