如果想对于基本函数进行一次封装比如说我调用基本函数fseek的时候错误的时候想要输出一句日志,每次都来一次下面的判断还是比较崩溃的.
if (fseek(...) != 0)
{
printf("fseek error %s\n", strerror(errno));
}
所以对于这种基本系统调用进行一个封装是比较好的一个思路, 第一个想到的就是下面这种思路,但是可以看到多少还是有点别扭
int fseek(FILE *stream, long offset, int whence);
#define FSEEK(stream, offset, whence, ret) \
do { \
ret = fseek(stream, offset, whence, ret); \
if (ret != 0) \
printf("xxxx"); \
} while(0)
int main()
{
...
int ret = 0;
FSEEK(stream, offset, whence, ret);
if (ret != 0)
{
return -1;
}
...
}
最后看到另外一个宏定义
#define FOPEN(path, mode) ({ \
FILE* ret = 0; \
ret = fopen(path, mode); \
if (ret == NULL)\
{ \
printf("err %s\n", strerror(errno)); \
} \
ret; \
})
int main(int argc, char** argv)
{
if (FOPEN(argv[1], "rb+") == NULL)
{
printf("open error");
}
}
其实上面的函数可以通过宏展开看下具体展开后 gcc -E test.cpp
int main(int argc, char** argv)
{
if (({ FILE* ret = 0; ret = fopen(argv[1], "rb+"); if (ret ==
((void *)0)
) { printf("err %s\n", strerror(
(*__errno_location ())
)); } ret; }) ==
((void *)0)
)
{
printf("open error");
}
}
整理后如下
int main(int argc, char** argv)
{
if ( ({
FILE* ret = 0;
ret = fopen(argv[1], "rb+");
if (ret == ((void *)0))
{ printf("err %s\n", strerror((*__errno_location ()))); }
ret; }) == ((void *)0)
)
{
printf("open error");
}
}