Skip to main content
Graduate II
February 12, 2024
Solved

while loop requires semicolon or not

  • February 12, 2024
  • 4 replies
  • 1496 views

When I run the below code snippet, it just runs for once, however when I added semicolon as in latter code piece, it runs as expected, continously.

Could you please tell me why is the difference?

/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
while(!(TIM6->SR & TIM_SR_UIF))
TIM6->SR = 0;
HAL_GPIO_TogglePin(GPIOD, green_Pin);

*************************THE SECOND CODE PIECE IS BELOW**************************************
}

/* USER CODE END 3 */
}

/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
while(!(TIM6->SR & TIM_SR_UIF));
TIM6->SR = 0;
HAL_GPIO_TogglePin(GPIOD, green_Pin);
}

/* USER CODE END 3 */
}
    This topic has been closed for replies.
    Best answer by waclawek.jan

    In the first case, this statement

    TIM6->SR = 0;

    is the *body* of the while cycle. It means, your cycle is "while TIM6_SR.UIF flag is zero, clear all flags".  Depending on the exact timing of timer and this cycle, it may be, that timer sets the UIF flag in between the test in while, and the zeroing, so that the test always sees this flag to be zero.

    The second case is correct, there is a body-less while which waits while TIM6_SR.UIF  and exits when TIM6_SR.UIF  is set; and after that the flags are zeroed.

    JW

    4 replies

    Technical Moderator
    February 12, 2024

    Hello,

    First, I edited the code section to be readable. So please next time use the </> button to insert your code.

    Second, I don't see any difference between the first code and the second one. Could you please separate the two blocks? 

    I don't think the below separator you put is on the right place. Please double check.

    *************************THE SECOND CODE PIECE IS BELOW**************************************

     

    Super User
    February 12, 2024

    In the first case, this statement

    TIM6->SR = 0;

    is the *body* of the while cycle. It means, your cycle is "while TIM6_SR.UIF flag is zero, clear all flags".  Depending on the exact timing of timer and this cycle, it may be, that timer sets the UIF flag in between the test in while, and the zeroing, so that the test always sees this flag to be zero.

    The second case is correct, there is a body-less while which waits while TIM6_SR.UIF  and exits when TIM6_SR.UIF  is set; and after that the flags are zeroed.

    JW

    Technical Moderator
    February 12, 2024

    I must consult an ophthalmologist as I didn't see the difference :grinning_face:..

    Graduate
    February 12, 2024

    Although I normally like very compact source-code, where I don't want anything in the while body I explicitly mark it as such using a visibly empty body:

    while(!(TIM6->SR & TIM_SR_UIF))
     { ; }

    This makes it clear that the body of the while loop is knowingly empty, and not just that I accidentally dropped a semicolon at the end of the line.

    Graduate II
    February 12, 2024

    Per C language it's going to depend if you have a compound statement or not.

    If you just want it to iterate on the test you follow it with a semi-colon

    If you want it to do other things repetitively use the compound statement.

    while(test); // this will loop whilst test is false, for variables, you'd want them as volatile if the might change, otherwise the optimizer may remove, or compromise the test.