cancel
Showing results for 
Search instead for 
Did you mean: 

while loop requires semicolon or not

demir
Senior II

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 */
}
1 ACCEPTED SOLUTION

Accepted Solutions

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

View solution in original post

5 REPLIES 5
SofLit
ST Employee

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**************************************

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

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

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Danish1
Lead II

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.

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. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..