easy c question regarding post increment and break from loop - Page 1
Forum section: electronics / general

author: snarkysparky
author_rank: Frequent Contributor
timestamp: November 17, 2022, 01:04:13 pm
content: This line is in a loopif (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

author: Ian.M
author_rank: Super Contributor
timestamp: November 17, 2022, 01:24:48 pm
content: 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.

author: Mechatrommer
author_rank: Super Contributor
timestamp: November 17, 2022, 01:34:39 pm
content: compare CMDPrefixFirstLocations first, and then increment CntrlPrefixIndex, and then break based on compare condition made earlier.

author: TheCalligrapher
author_rank: Regular Contributor
timestamp: November 17, 2022, 07:18:59 pm
content: Quote from: snarkysparky on November 17, 2022, 01:04:13 pmYes, it is. `CntrlPrefixIndex++` is evaluated before the `break`. That means the increment is always done.Quote from: Ian.M on November 17, 2022, 01:24:48 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`.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 17, 2022, 07:28:39 pm
content: Quote from: Ian.M on November 17, 2022, 01:24:48 pmYes. 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.

author: DavidAlfa
author_rank: Super Contributor
timestamp: November 17, 2022, 07:32:19 pm
content: Code:if (CMDPrefixFirstLocations[CntrlPrefixIndex++] <= CharLp) break;^Increased here, before taking any actionIf you want to avoid that:Code:if (CMDPrefixFirstLocations <= CharLp) break;CntrlPrefixIndex++; // This won't happen if it did the break

author: newbrain
author_rank: Super Contributor
timestamp: November 17, 2022, 08:56:32 pm
content: Quote from: TheCalligrapher on November 17, 2022, 07:18:59 pmExactly 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).Quote from: Ian.M on November 17, 2022, 01:24:48 pmForgetting 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.

author: Mechatrommer
author_rank: Super Contributor
timestamp: November 17, 2022, 09:19:38 pm
content: Quote from: SiliconWizard on November 17, 2022, 07:28:39 pmthis 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:if (a[b++] < c) break;or..Code:if (a < c) {b++;break;} else {b++;}are semantically the same.

author: newbrain
author_rank: Super Contributor
timestamp: November 17, 2022, 09:32:53 pm
content: Quote from: Mechatrommer on November 17, 2022, 09:19:38 pmNope.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:int b;int a(int x) { return x + b; }Might execute different branches in the two versions.

author: TheCalligrapher
author_rank: Regular Contributor
timestamp: November 17, 2022, 09:35:20 pm
content: Quote from: Mechatrommer on November 17, 2022, 09:19:38 pmYour second version suffers from violation of DRY ("Don't Repeat Yourself") principle. A typical alternative would normally look asCode:x = b;++b;if (a(x) < c)break;or asCode:bool is_done = a(b) < c;++b;if (is_done)break;(assuming that there are no issues mentioned bynewbrainabove)

author: Mechatrommer
author_rank: Super Contributor
timestamp: November 17, 2022, 10:09:00 pm
content: Quote from: newbrain on November 17, 2022, 09:32:53 pmsorry that was a serious typo (semantic error)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.Quote from: TheCalligrapher on November 17, 2022, 09:35:20 pmthose suffer WTRV (whats that redundant variable?) and TCTR (too cryptic to read)

author: TheCalligrapher
author_rank: Regular Contributor
timestamp: November 17, 2022, 10:31:01 pm
content: Quote from: Mechatrommer on November 17, 2022, 10:09:00 pmWell, 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.

author: newbrain
author_rank: Super Contributor
timestamp: November 18, 2022, 12:11:09 am
content: Quote from: Mechatrommer on November 17, 2022, 10:09:00 pmNo, 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.