Макросы и проверка аргументов
От: PlusMyTwitterFace  
Дата: 30.07.12 19:41
Оценка:
Приветствую.

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

Например:

void foo(int* first)
{
    if (!first)
    {
        std::cerr << "Error \n";
        return;
    }
}

void bar(int* first, int* second)
{
    if (!first || !second)
    {
        std::cerr << "Error \n";
        return;
    }
}


И т.д.

Писать каждый раз всё это руками — как-то утомительно, а копипастить не хочется (легко забыть добавить ещё одну проверку, а потом целый день потратить на поиски бага).

Захотелось мне придумать что-нибудь наподобие хитрого макроса с переменным числом аргументов, который бы можно было использовать, например, так:

VALIDATE_INPUT_PARAMETERS(first, second);


А он бы сам раскрывался в то, что мне требуется.

Но вот незадача — как это реализовать (даже с учётом Variadic Macros из C99 / C++11) я, к сожалению, не знаю.

На ум приходит лишь решение в виде Variadic макроса, который список аргументов передаёт на вход некоторой функции с переменным числом аргументов, а уже в её теле мы вытаскиваем все аргументы и проверяем их.

Но, я думаю, что жестоко туплю, и более корректное решение данной задачи всё же существует.
Re: Макросы и проверка аргументов
От: PlusMyTwitterFace  
Дата: 30.07.12 19:43
Оценка:
Решение желательно, конечно, кросс-платформенное, но если получится написать лишь для конкретного компилятора — буду признателен.
Re: Макросы и проверка аргументов
От: Caracrist https://1pwd.org/
Дата: 30.07.12 19:57
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>
PMT>VALIDATE_INPUT_PARAMETERS(first, second);
PMT>


#define VALIDATE_INPUT_PARAMETERS(...) void*tests[] = {__VA_ARGS__};\
 for (size_t i = 0; i < sizeof(tests)/sizeof(void*); i++){ if (!tests[i]) \
{ std::cerr << "Error \n"; return; }}

~~~~~
~lol~~
~~~ Single Password Solution
Re: Макросы и проверка аргументов
От: profsha  
Дата: 30.07.12 20:05
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>Приветствую.


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


в с++ существуют функции с переменным количеством аргументов... чем они не подходят?
Re: Макросы и проверка аргументов
От: night beast СССР  
Дата: 31.07.12 03:34
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>Приветствую.


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


PMT>Писать каждый раз всё это руками — как-то утомительно, а копипастить не хочется (легко забыть добавить ещё одну проверку, а потом целый день потратить на поиски бага).


PMT>Захотелось мне придумать что-нибудь наподобие хитрого макроса с переменным числом аргументов, который бы можно было использовать, например, так:


PMT>
PMT>VALIDATE_INPUT_PARAMETERS(first, second);
PMT>


PMT>А он бы сам раскрывался в то, что мне требуется.


PMT>Но вот незадача — как это реализовать (даже с учётом Variadic Macros из C99 / C++11) я, к сожалению, не знаю.


здесь
Автор: remark
Дата: 26.05.10


ну или в бусте для подобных штук что-то было.
Re: Макросы и проверка аргументов
От: uzhas Ниоткуда  
Дата: 31.07.12 07:19
Оценка:
Здравствуйте, PlusMyTwitterFace, Вы писали:

PMT>Но, я думаю, что жестоко туплю, и более корректное решение данной задачи всё же существует.


1) use references, Luke!
2) напиши макрос для одного аргумента и заюзай его для каждого аргумента:
void bar(int* first, int* second)
{
  VALIDATE_PARAM(first);
  VALIDATE_PARAM(second);
  //use input params
}

3) можешь наштамповать макросы под несколько аргументов, подход не так тяжел, как кажется
Re: Макросы и проверка аргументов
От: Vamp Россия  
Дата: 31.07.12 12:56
Оценка: +2
PMT>Но, я думаю, что жестоко туплю, и более корректное решение данной задачи всё же существует.
Сушествует — не выполнять таких проверок внутри функций. Бессмысленная трата процессорных циклов. Я еще понимаю дебаговый ассерт (хотя тоже не считаю его нужным). А продакшн-return — это ересь.
Да здравствует мыло душистое и веревка пушистая.
Re: Макросы и проверка аргументов
От: nen777w  
Дата: 31.07.12 13:25
Оценка:
PMT>Имеется много функций, которые принимают в качестве аргументов указатели на какие-либо данные, которые в теле этой функции, само собой разумеется, необходимо разыменовывать, чтобы добраться до того, на что они, собственно, указывают. Аргументов бывает абсолютно разное кол-во. Делать во всех подобных случаях мне необходимо одно и то же (допустим, писать сообщение в лог об ошибке и делать return из текущей функции).


#define _SEQ_ENUM_MACRO(r, data, elem) data elem

#define SEQ_ENUM( seq, enum_separator ) \
    BOOST_PP_SEQ_HEAD(seq) \
    BOOST_PP_SEQ_FOR_EACH(_SEQ_ENUM_MACRO, enum_separator, BOOST_PP_SEQ_TAIL(seq) )



SEQ_ENUM((!first), ||) -> !first
SEQ_ENUM((!first)(!second), ||) -> !first  || !second
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.