Я перепроектировал какой-то код и наткнулся на это ...
/************************************************************************/
/* */
/* MACRO CHECK_FREAD */
/* */
/* CHECK_FREAD is used to check the status of a file read. It */
/* is passed the return code from read and a string to print out if */
/* an error is detected. If an error is found, an error message is */
/* printed out and the program terminates. This was made into a */
/* macro because it had to be done over and over and over . . . */
/* */
/************************************************************************/
#define CHECK_FREAD(X, msg) if (X==-1) \
{ \
return(DCD_BADREAD); \
}
По сути, конкретный набор функций в этом файле вызывает это всякий раз, когда они выполняют (c-чтение), чтобы проверить результат на наличие ошибки. У них также есть аналогичная проверка для EOF ... В основном, насколько я могу судить, они делают это таким образом, чтобы вставить возврат при ошибке в середине своей функции в кучу мест.
e.g.
/* Read in an 4 */
ret_val = read(fd, &input_integer, sizeof(int32));
CHECK_FREAD(ret_val, "reading an 4");
CHECK_FEOF(ret_val, "reading an 4");
if (input_integer != 4)
{
return(DCD_BADFORMAT);
}
/* Read in the number of atoms */
ret_val = read(fd, &input_integer, sizeof(int32));
*N = input_integer;
CHECK_FREAD(ret_val, "reading number of atoms");
CHECK_FEOF(ret_val, "reading number of atoms");
Сейчас я только возвращаюсь к программированию на c / c ++ и вообще никогда не использовал много макросов, но разве это злоупотребление макросами?
Я читал это ... Когда макросы C ++ полезны?
... и это не похоже ни на один из кошерных примеров, поэтому я предполагаю, что "ДА". Но я хотел получить более информированное мнение, а не просто делать обоснованные предположения ... :)
... эээ, а не лучше ли использовать какую-нибудь обертку?
size_t checked_fread(void *buffer, size_t itemsize, size_t numitems, FILE *fp, const char *msg)
функцию и использовать ее последовательно. Также интересно порассуждать, почему он проверяет по -1;fread()
возвращает 0 или короткий счетчик ошибок, а тип возврата -size_t
, что исключает возвращаемое значение -1 почти для всех целей. - person Jonathan Leffler   schedule 02.09.2010fread()
не имеют отношения кread()
. Поскольку мы не видим CHECK_FEOF (), мы не можем сказать, что он делает. Однако мне кажется, что простая функция для обработки обоих условий была бы лучше: она могла бы обернуть функциюread()
(системный вызов) и отделить статус ошибки от всего остального:if ((retval = wrapped_read(fd, &input_integer, sizeof(int32), "reading a 4")) != DCD_NOERROR) return retval;
. И если тест на 4 будет повсеместным, я бы закончил это еще дальше. Я считаю, что это злоупотребление макросами. - person Jonathan Leffler   schedule 02.09.2010