这会被优化吗?

时间:2011-09-11 17:14:28

标签: c++ c optimization

我的断言宏是这样的:

#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),但究竟是什么条件可以保证呢?是否存在任何具有副作用的操作,优化器可能会抛出这些操作?

2 个答案:

答案 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