Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2021.1

Wiki MarkupAn empty infinite loop that does not do anything within the loop body is a suboptimal solution, and no code should use it. The solution is suboptimal because it consumes CPU cycles but does nothing. An optimizing compiler can remove such a loop, and it can lead to unexpected results. According to C1X Committee Draft \[[ISO/IEC 9899:201x|AA. Bibliography#ISO/IEC 9899-201x]\], Section 6.8.5.6

An iteration statement 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.155

...

loop with an empty body consumes CPU cycles but does nothing. Optimizing compilers and just-in-time systems (JITs) are permitted to (perhaps unexpectedly) remove such a loop. Consequently, programs must not include infinite loops with empty bodies.

Noncompliant Code Example

This noncompliant code example implements an idle task that continuously executes a loop without executing any instructions within the loop. An optimizing compiler or JIT could remove the while loop in the this example.

Code Block
bgColor#FFCCCC

public int mainnop(void) {
  while (1true) { }
}

Compliant Solution (

...

To avoid optimizing out of the loop, this compliant solution uses instructions that give up the CPU within the while loop. On POSIX platform, sleep(3) can be used. Other platforms might have equivalent functions.

Code Block
bgColor#ccccff

int main(void) {
  while(1) {
    sleep(DURATION);
  }
}

Noncompliant Code Example

This noncompliant code example sets up interrupt handlers to process packets coming in from the network. It then waits for interrupts within a loop. Any interrupt causes the rcv_intr() function to be invoked.

However, an optimizing compiler could remove the for loop in the example. This example also violates the recommendation SIG02-C. Avoid using signals to implement normal functionality.

Code Block
bgColor#FFCCCC

int main(void) {
  /* set up buffers, signal handlers for interrupts, etc. */
  /* ... */
  for ( ; ; ) {
    ;	/* let interrupt handler do all the work */
  }
  /* not reached */
}

void rcv_intr(int interrupt) { /* signal handler entered upon data_available interrupt */
  /* ... */
  get_packet();  /* read the packet */
  if (packet.hdr.service == ICMP_ECHO) {
    send_packet();  /* send the packet */
  }
  /* ... */
}

Compliant Solution (POSIX)

This compliant solution avoids optimizing out the loop by using instructions that give up the CPU within the for loop. On POSIX platform, sleep(3) can be used. Other platforms might have equivalent functions.

Code Block
bgColor#ccccff

int main(void) {
  /* set up buffers, signal handlers for interrupts, etc. */
  /* ... */
  for ( ; ; ) {
    sleep(DURATION);	/* let interrupt handler do all the work */
  }
  /* not reached */
}

void rcv_intr(int interrupt) { /* signal handler entered upon data_available interrupt */
  /* ... */
  get_packet();  /* read the packet */
  if (packet.hdr.service == ICMP_ECHO) {
    send_packet();  /* send the packet */
  }
  /* ... */
}

Exceptions

MSC40-EX1: In rare cases, use of an empty infinite loop may be unavoidable. For instance, an empty loop may be necessary on a platform that does not support sleep(3) or an equivalent function. Another example occurs in operating system kernels. A task started before normal scheduler functionality is available may not have access to sleep(3) or an equivalent function. In such a case, it is necessary to adopt alternative solutions that prevent an optimizing compiler from removing the empty infinite loop.

The following solution uses a volatile variable.

Code Block
bgColor#ccccff

int main(void) {
  volatile int true_value = 1;
  while (true_value) { }
}

The following solution is specific to the GCC 4.4.0 (or newer) compiler. It uses the optimize function attribute to turn off optimization at a function level, without disabling optimization for the rest of the code.

Thread.sleep())

This compliant solution avoids use of a meaningless infinite loop by invoking Thread.sleep() within the while loop. The loop body contains semantically meaningful operations and consequently cannot be optimized away.

Code Block
bgColor#ccccff
public final int DURATION=10000; // In milliseconds

public void nop() throws InterruptedException {
  while (true) {
    // Useful operations
    Thread.sleep(DURATION);
  }
}

Compliant Solution (yield())

This compliant solution invokes Thread.yield(), which causes the thread running this method to consistently defer to other threads:

Code Block
bgColor#ccccff
public void nop() {
  while (true) {
    Thread.yield();
  
Code Block
bgColor#ccccff

int main(void) __attribute__ ((optimize("O0")));

int main(void) {
  while (1) { }
}

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC40

MSC01-

C

J

low

Low

unlikely

Unlikely

medium

Medium

P2

L3

Bibliography

ISO/IEC 9899:201x Committee Draft October 4, 2010 N1516 Section 6.8.5, Iteration statements.

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.MSC01.EBAvoid control statements with empty bodies
SonarQube3.10S2189

Bibliography


...

Image Added Image Added Image AddedMSC39-C. Do not call va_arg() on a va_list that has indeterminate value      49. Miscellaneous (MSC)      50. POSIX (POS)