How do I make an infinite empty loop that won't be optimized away?

前端 未结 13 1420
后悔当初
后悔当初 2020-12-23 13:16

The C11 standard appears to imply that iteration statements with constant controlling expressions should not be optimized out. I\'m taking my advice from this answer, which

相关标签:
13条回答
  • 2020-12-23 13:45

    I'll play the devil's advocate and argue that the standard does not explicitly forbid a compiler from optimizing out an infinite loop.

    An iteration statement whose controlling expression is not a constant expression,156) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression-3, may be assumed by the implementation to terminate.157)

    Let's parse this. An iteration statement that satisfies certain criteria may be assumed to terminate:

    if (satisfiesCriteriaForTerminatingEh(a_loop)) 
        if (whatever_reason_or_just_because_you_feel_like_it)
             assumeTerminates(a_loop);
    

    This doesn't say anything about what happens if the criteria aren't satisfied and assuming that a loop may terminate even then isn't explicitly forbidden as long as other rules of the standard are observed.

    do { } while(0) or while(0){} are after all iteration statements (loops) that don't satisfy the criteria that allow a compiler to just assume on a whim that they terminate and yet they obviously do terminate.

    But can the compiler just optimize while(1){} out?

    5.1.2.3p4 says:

    In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

    This mentions expressions, not statements, so it's not 100% convincing, but it certainly allows calls like:

    void loop(void){ loop(); }
    
    int main()
    {
        loop();
    }
    

    to be skipped. Interestingly, clang does skip it, and gcc doesn't.

    0 讨论(0)
提交回复
热议问题