Вопрос

// Example assert function
inline void assertImpl(bool mExpr, const std::string& mMsg) {
    if(!mExpr) { printMsg(mMsg); abortExecution(); }
}

// Wrapper macro
#ifdef NDEBUG
    #define MY_ASSERT(...) do{ ; }while(false)
#else
    #define MY_ASSERT(...) assertImpl(__VA_ARGS__)
#endif

Consider the case where mExpr or mMsg are not-pure expressions - is there a way to force the compiler to optimize them out anyway?

bool globalState{false};
bool pureExpression() { return false; }
bool impureExpression() { globalState = !globalState; return false; }

// ...

// This will very likely be optimized out with (NDEBUG == 0)
MY_ASSERT(pureExpression());

// Will this be optimized out with (NDEBUG == 0)
MY_ASSERT(impureExpression());
  • What do compilers usually do in a situation where an impure expression is "discarded"?
  • Is there a way to make 100% sure that pure expressions get optimized out?
  • Is there a way to make 100% sure that impure expressions get optimized out or never get optimized out?
Это было полезно?

Решение

After macro expansion, your call to impureExpression() no longer exists: it's not part of the macro expansion result. If the call to your function isn't there, the function won't be called, on all conforming implementations, at any optimisation level, as long as NDEBUG is defined.

Note: you talk about NDEBUG == 0, but if that is what you want the condition to be, your #ifdef NDEBUG condition is incorrect. #ifdef tests whether the macro is defined, and pays no attention to what the definition is.

Другие советы

The optimizer is not involved here. In the macro that is enabled with NDEBUG, the arguments are discarded regardless.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top