谨防define宏陷阱

最近在研究Deduplication(重复数据删除)存储技术,实现一个dedup原型系统,结果在Coding中遇到了一个莫名其妙的问题。简略代码如下:

#include "dedup.h" #ifndef BLOCK_LEN #define BLOCK_LEN 32 * 1024 /* 32K Bytes */ #endif #define BACKET_SIZE 10240 ... int fd_src, fd_dest; char buf[BLOCK_LEN] = {0}; unsigned int rwsize, pos, block_id; unsigned char md5_checksum[16] = {0}; unsigned int *metadata = NULL; unsigned int block_num = 0; struct stat stat_buf; hashtable *htable = NULL; dedup_file_header dedup_hdr; ... if (-1 == (fd_src = open(argv[1], O_RDONLY))) { perror("open source file"); return errno; } ... htable = create_hashtable(BACKET_SIZE); if (NULL == htable) { perror("create_hashtable"); return errno; } pos = 0; block_id = 0; if (-1 == fstat(fd_src, &stat_buf)) { perror("fstat source file"); goto _EXIT; } block_num = stat_buf.st_size / BLOCK_LEN; metadata = (unsigned int *)malloc(sizeof(unsigned int) * block_num); if (metadata == NULL) { perror("malloc metadata"); goto _EXIT; }

 

 我用大小为1.9MB的文件作为源文件,结果 block_num 居然为 61881344,真是出乎想像。块大小BLOCK_LEN = 32KB,所以block_num应该为59才对。问题出在哪了呢?这段代码非常简单了,没有什么复杂的逻辑,我反复review了几次也没有发现问题。于是,在家里转了两圈,然后无意中注意到了BLOCK_LEN的宏定义。define总是容易犯些低级的错误,难道我也犯了最低级的错误不成?

#define BLOCK_LEN       32 * 1024 /* 32K Bytes */

看到这行,我当时就傻了,自己还真犯了最低级、最原始的错误。

block_num = stat_buf.st_size / BLOCK_LEN;

上面这行宏替换后就成了:

block_num = stat_buf.st_size / 32 * 1024;

终于明白问题出在何处了,给宏加上(),即#define BLOCK_LEN       (32 * 1024) ,一切OK了!

这次经验教训深刻,估计我以后很少会再犯类似错误了,另外也小有收获和乐趣  ^-^。

最后提醒一下:宏使用很方便,但要谨慎使用,尤其需要注意书写格式,尽量多用括号避免歧义。细节是魔鬼!

你可能感兴趣的:(struct,File,header,null,存储)