我在反向工程一些代码时遇到了这个...
/************************************************************************/
/* */
/* 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-read)以检查错误结果时都会调用此函数。他们还有一个类似的EOF检查... 就我所知,他们这样做是为了在许多地方的函数中在错误处插入返回。
例如:
/* 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++编程,而且我从来没有经常使用过宏,但是这个宏的使用是否合理呢?
我读了这篇文章...When are C++ macros beneficial?
...听起来不像任何一种正常的例子,所以我的猜测是“是”。但是我想得到一个更有见地的意见,而不仅仅是做出有根据的猜测... :)
...额,使用一些包装方法不会更好吗?
size_t checked_fread(void *buffer, size_t itemsize, size_t numitems, FILE *fp, const char *msg)
函数并始终使用它。有趣的是推测为什么要检查-1;fread()
在出错时返回0或短计数-而返回类型为size_t
,几乎所有目的都不允许返回值为-1。 - Jonathan Lefflerfread()
的评论与read()
不相关。由于我们看不到CHECK_FEOF(),我们无法知道它的作用。不过,在我看来,编写一个简单的函数来处理这两种情况会更好:它可以包装read()
函数(系统调用)并将错误状态与其他内容分离出来:if ((retval = wrapped_read(fd, &input_integer, sizeof(int32), "reading a 4")) != DCD_NOERROR) return retval;
。如果对4的测试普遍存在,我会进一步封装它。我认为这是宏滥用。 - Jonathan Leffler