Author Topic: easy c question regarding post increment and break from loop  (Read 1739 times)

0 Members and 1 Guest are viewing this topic.

Offline snarkysparkyTopic starter

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: us
easy c question regarding post increment and break from loop
« on: November 17, 2022, 01:04:13 pm »
This line is in a loop

if (CMDPrefixFirstLocations[CntrlPrefixIndex++] <= CharLp) break;

If the break is executed is the last  CntrlPrefixIndex++   done before the break.

In other words will the loop exit with CntrlPrefixIndex at the index that caused the break or will it be 1 more than that.

Thanks  C   experts
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13132
Re: easy c question regarding post increment and break from loop
« Reply #1 on: November 17, 2022, 01:24:48 pm »
The post-increment is applied after evaluating the expression for the if condition *BEFORE* executing the block controlled by the if statement.
 If you don't want the increment to happen on the last pass, you need to move it out of the condition and into a new else block.
 
The following users thanked this post: snarkysparky

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11713
  • Country: my
  • reassessing directives...
Re: easy c question regarding post increment and break from loop
« Reply #2 on: November 17, 2022, 01:34:39 pm »
compare CMDPrefixFirstLocations[CntrlPrefixIndex] first, and then increment CntrlPrefixIndex, and then break based on compare condition made earlier.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: snarkysparky

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 159
  • Country: us
Re: easy c question regarding post increment and break from loop
« Reply #3 on: November 17, 2022, 07:18:59 pm »
This line is in a loop

if (CMDPrefixFirstLocations[CntrlPrefixIndex++] <= CharLp) break;

If the break is executed is the last  CntrlPrefixIndex++   done before the break.

Yes, it is. `CntrlPrefixIndex++` is evaluated before the `break`. That means the increment is always done.

The post-increment is applied after evaluating the expression for the if condition *BEFORE* executing the block controlled by the if statement.

"after evaluating the expression for the if condition"? No, you can't make claims like that. No one knows when post-increment is physically applied within this expression. And it doesn't really matter. The only thing that matters is that the subscripting is guaranteed to use the original ("old", "before increment") value of `CntrlPrefixIndex`.
« Last Edit: November 17, 2022, 08:34:03 pm by TheCalligrapher »
 
The following users thanked this post: newbrain

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15439
  • Country: fr
Re: easy c question regarding post increment and break from loop
« Reply #4 on: November 17, 2022, 07:28:39 pm »
The post-increment is applied after evaluating the expression for the if condition *BEFORE* executing the block controlled by the if statement.
 If you don't want the increment to happen on the last pass, you need to move it out of the condition and into a new else block.

Yes. And while this is perfectly valid C (if that was what was intended), I personally recommend avoiding using pre/post-incrementation/decrementation combined with accessing the value.
It tends to make your code a bit harder to read (even if you are a very seasoned C programmer, it will always take a couple seconds more to figure out and there's no good rationale for that IMHO) and is a nice source of potential bugs just like with the example code you provided.

Generally speaking, avoid expressions that can do several things at the same time. But of course that is just advice and I'm sure you'll find a lot of contradicting advice about that out there.

 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6273
  • Country: es
Re: easy c question regarding post increment and break from loop
« Reply #5 on: November 17, 2022, 07:32:19 pm »
Code: [Select]
if (CMDPrefixFirstLocations[CntrlPrefixIndex++] <= CharLp) break;
                                              ^             
                                              Increased here, before taking any action

If you want to avoid that:
Code: [Select]
if (CMDPrefixFirstLocations[CntrlPrefixIndex] <= CharLp) break;
CntrlPrefixIndex++;                                                    // This won't happen if it did the break
« Last Edit: November 17, 2022, 07:33:57 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1772
  • Country: se
Re: easy c question regarding post increment and break from loop
« Reply #6 on: November 17, 2022, 08:56:32 pm »
after evaluating the expression for the if condition"? No, you can't make claims like that. No one knows when post-increment is physically applied within this expression. And it doesn't really matter. The only thing that matters is that the subscripting is guaranteed to use the original ("old", "before increment") value of `CntrlPrefixIndex`.
Exactly so.
The only guarantee we have is that the side effects are complete at each sequence point, but there are  no requirements on the side effects ordering and place while evaluating each full expression.
Post increment is a side effect, and there is a sequence point between the end of the if control (full) expression and a following full expression.
(C11, Annex 3 - sequence points).

The post-increment is applied after evaluating the expression for the if condition *BEFORE* executing the block controlled by the if statement.
 If you don't want the increment to happen on the last pass, you need to move it out of the condition and into a new else block.
Forgetting the "after evaluating" that's been already discussed, and spraining my nitpick ligament  ::), I would object that the standard does not really force the side effect to complete before the break is executed.
Sequence points are only defined in terms of evaluations and break is not an expression, albeit it's guaranteed that there'll be a SP before the result of the side effect (++) can be used in any way.
A smart compiler might notice that all program paths will somehow yield an incremented CntrlPrefixIndex and place its actual increment in a more optimal position.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11713
  • Country: my
  • reassessing directives...
Re: easy c question regarding post increment and break from loop
« Reply #7 on: November 17, 2022, 09:19:38 pm »
The post-increment is applied after evaluating the expression for the if condition *BEFORE* executing the block controlled by the if statement.
 If you don't want the increment to happen on the last pass, you need to move it out of the condition and into a new else block.

Yes. And while this is perfectly valid C (if that was what was intended), I personally recommend avoiding using pre/post-incrementation/decrementation combined with accessing the value.
It tends to make your code a bit harder to read (even if you are a very seasoned C programmer, it will always take a couple seconds more to figure out and there's no good rationale for that IMHO) and is a nice source of potential bugs just like with the example code you provided.

Generally speaking, avoid expressions that can do several things at the same time. But of course that is just advice and I'm sure you'll find a lot of contradicting advice about that out there.
this is a conflict (or a compromise) issue... that "feature" is for shortcut to reduce number of code lines and fatigue hand (pro) but can be harder to read/comprehend (con) if not well versed in the language, try to be traditious as you've suggested can be easier to read and avoid bug risk (pro) but requires more line of codes (con), so i say both techniques are rational to use... imho one can freely choose...

Code: [Select]
if (a[b++] < c) break;

or..

Code: [Select]
if (a[b] < c) {
  b++;
  break;
} else {
  b++;
}

are semantically the same.
« Last Edit: November 17, 2022, 09:56:55 pm by Mechatrommer »
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 
The following users thanked this post: lyxmoo

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1772
  • Country: se
Re: easy c question regarding post increment and break from loop
« Reply #8 on: November 17, 2022, 09:32:53 pm »
are semantically the same.
Nope.
Or at least, you can't say without seeing what's inside function a().
There is a sequence point before the effective function call, at the end of the arguments evaluation.

So:
Code: [Select]
int b;

int a(int x) { return x + b; }
Might execute different branches in the two versions.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 159
  • Country: us
Re: easy c question regarding post increment and break from loop
« Reply #9 on: November 17, 2022, 09:35:20 pm »
Code: [Select]
if (a(b++) < c) break;

or..

Code: [Select]
if (a(b) < c) {
  b++;
  break;
} else {
  b++;
}

are semantically the same.

Your second version suffers from violation of DRY ("Don't Repeat Yourself") principle. A typical alternative would normally look as

Code: [Select]
x = b;
++b;
if (a(x) < c)
  break;

or as

Code: [Select]
bool is_done = a(b) < c;
++b;
if (is_done)
  break;

(assuming that there are no issues mentioned by newbrain above)
« Last Edit: November 17, 2022, 09:38:03 pm by TheCalligrapher »
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11713
  • Country: my
  • reassessing directives...
Re: easy c question regarding post increment and break from loop
« Reply #10 on: November 17, 2022, 10:09:00 pm »
are semantically the same.
Nope.
sorry that was a serious typo (semantic error) :palm: i meant array element like in OP (as i am also program in VB which use () as array indexing) typo corrected. but i think even if its meant a function call, your function example will give same result on both of the code variant. but that besides the point. ymmv.

Code: [Select]
x = b;
++b;
if (a(x) < c)
  break;

or as

Code: [Select]
bool is_done = a(b) < c;
++b;
if (is_done)
  break;

those suffer WTRV (whats that redundant variable?) and TCTR (too cryptic to read) ;D
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 159
  • Country: us
Re: easy c question regarding post increment and break from loop
« Reply #11 on: November 17, 2022, 10:31:01 pm »
those suffer WTRV (whats that redundant variable?) and TCTR (too cryptic to read) ;D

Well, one cure to WTRV problem is the original version suffering from DTMTAO ("doing too many things at once") syndrome (which is a strain of TCTR), so we are back to square one: it is either WTRV or DRY or DTMTAO/TCTR. Choose your poison.

However, both WTRV and TCTR is easily alleviated by NYVD ("name your variables descriptively") techinque. So, while my `x` might be suffering from a case of WTRV, my `is_done` is completely imprevious to it.

« Last Edit: November 17, 2022, 10:34:00 pm by TheCalligrapher »
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1772
  • Country: se
Re: easy c question regarding post increment and break from loop
« Reply #12 on: November 18, 2022, 12:11:09 am »
I think even if its meant a function call, your function example will give same result on both of the code variant. but that besides the point.
No, they won't (in general).
Try with b=0 and c=1.
Partly beside the point with your update.
Only partly as the point is, in fact, sequence points. :blah:
Nandemo wa shiranai wa yo, shitteru koto dake.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf