我的断言宏是这样的:
#ifdef DEBUG
#define ASSERT(x) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (exit(-1), 1)))
#else
#define ASSERT(x) ((void)sizeof(x))
我认为这或多或少是防弹的,但我似乎在断言函数的返回值的上下文中使用它很多,这些函数对于它们的副作用很重要。如果在我的发布版本中我最终编译
ASSERT(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file));
将成为
((void)sizeof(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file)));
这是否有可能完全优化?我相当肯定它不会(我正在调用一个函数fgets
),但究竟是什么条件可以保证呢?是否存在任何具有副作用的操作,优化器可能会抛出这些操作?
答案 0 :(得分:4)
它与优化无关。评估sizeof
表达式时,操作数永远不会被评估。例如,
char func(void) { exit(1); }
size_t sz = sizeof(func());
// same as
size_t sz = 1;
如果你想在不产生编译器警告的情况下保留副作用,可以像Neil G在他的回答中所说的那样强制转换为void
。
答案 1 :(得分:3)
断言的通常含义是要进行优化,因此坚持使用这些语义可能会更好
#else
#define ASSERT(x)
#endif
如果你坚持不进行优化,为什么不做呢?
#else
#define ASSERT(x) ((void)(x))
#endif