Recent

Author Topic: how to break out early of a case ?  (Read 79968 times)

440bx

  • Hero Member
  • *****
  • Posts: 5466
Re: how to break out early of a case ?
« Reply #195 on: May 25, 2025, 01:19:05 am »
seems to me that you don't need a "fall", just a "next".

Basically, whenever execution has to go to the next case then simply use "next".

As far as the condition, only the initial condition should be tested because "fall"/"next" is a _command_ to execute the next case's code. 

The whole point of C's switch is to allow code to be additive while selecting the "addition's stack" starting point.

IOW, the cases are there only to select the code's "entry"/"starting" point.  Once that has been selected, what happens is determined by "next" (to keep executing) or nothing to exit the case/switch.

When the code is generated, the absence of a "next" tells the compiler to put a jump to the end of case's code.  if there is a next then simply let execution continue.  Code-wise, it's very cheap.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #196 on: May 25, 2025, 01:53:35 am »
As far as the condition, only the initial condition should be tested because "fall"/"next" is a _command_ to execute the next case's code. 

The difference between fall and next might be useful for state machine like programming. Both result in very cheap code (jump instruction).
« Last Edit: May 25, 2025, 10:14:11 am by munair »
It's only logical.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8431
Re: how to break out early of a case ?
« Reply #197 on: May 25, 2025, 09:31:53 am »
As far as the condition, only the initial condition should be tested because "fall"/"next" is a _command_ to execute the next case's code. 

The whole point of C's switch is to allow code to be additive while selecting the "addition's stack" starting point.

Deferring to you as OP, but I feel that this sort of situation would justify a ground-up reexamination of the semantics of the case (or switch etc.) statement and the distinction between case labels and ordinary labels used as a target by goto.

It might even make sense to rule that goto can /only/ be used in the context of a case statement (removing the explicit label statement from the language), in which case goto with no explicit target could be used as a controlled way of exiting the entire case statement.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 5466
Re: how to break out early of a case ?
« Reply #198 on: May 25, 2025, 10:46:37 am »
Personally, I find the C switch would be just fine if fall-through was _not_ the default.

IOW, a case/switch where fall-through must be explicitly caused by an instruction is what I consider to be ideal.  IMO, C got it "almost right".

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #199 on: May 25, 2025, 11:35:14 am »
C behaves like a fall-through (evaluates everything else too, unless break) where Pascal exits when a condition is satisfied.

As you can see from this thread, there is even confusion about the fall-through behavior in C. Does it evaluate subsequent branch conditions once a match is found, or does it simply execute all following code ignoring the branch conditions? That's why I think it's better to be able to make that distinction in the code.

I also wonder if there has ever been an explanation for C's odd switch-behavior.
It's only logical.

Thaddy

  • Hero Member
  • *****
  • Posts: 17176
  • Ceterum censeo Trump esse delendam
Re: how to break out early of a case ?
« Reply #200 on: May 25, 2025, 11:42:10 am »
Unless Break is encountered C will keep evaluating every switch.You can see it like this:
In Pascal a case is a single statement of if then else if else etc..
In C a switch is a series of if then, without the else.

So unlike C, Pascal always breaks out early... And C needs break for that.
« Last Edit: May 25, 2025, 11:45:19 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #201 on: May 25, 2025, 12:02:58 pm »
I'm not a C programmer, but I come across documentation that states:

Quote
control falls through to the statements after that switch label, even though the switch expression is not equal to the value of the fallen-through label.
It's only logical.

440bx

  • Hero Member
  • *****
  • Posts: 5466
Re: how to break out early of a case ?
« Reply #202 on: May 25, 2025, 12:14:10 pm »
That quote should be repeated:
Quote
control falls through to the statements after that switch label, even though the switch expression is not equal to the value of the fallen-through label.
Only one condition determines the starting point where code that is part of the switch will be executed.  Once the entry point is determined, all other conditions are for all intents and purposes: non-existent.



(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #203 on: May 25, 2025, 12:24:50 pm »
While I can't find documentation explaining the roots of C's switch behavior, one can guess why this was a design choice. Its predecessor BCPL had a switch construct that allowed control to flow through cases, and C probably inherited this behavior, providing continuity for programmers familiar with those languages. It kept the switch statement simple, matching earlier languages. Wirth was wise enough not to follow that design choice. But we're basically dealing with limitations either way that survived through recent decades in the name of compatibility.

« Last Edit: May 25, 2025, 12:27:24 pm by munair »
It's only logical.

Thaddy

  • Hero Member
  • *****
  • Posts: 17176
  • Ceterum censeo Trump esse delendam
Re: how to break out early of a case ?
« Reply #204 on: May 25, 2025, 01:10:32 pm »
Correct. It stems from BPCL and B.
K&R explained the rationale of the design that it can be seen as a collection of labels.

You can find the documentation in the famous "The C programming language" (section 3.4)

The C99 document is of a different opinion, though:
The C99 Rationale document states: "The fall-through behavior of the switch statement has been a fertile source of bugs, but it is retained because it is useful for some programming patterns." (section 56.8.4.2)

IOW it is retained because an anti-pattern can be a correct pattern in corner cases.
« Last Edit: May 26, 2025, 08:32:07 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 17176
  • Ceterum censeo Trump esse delendam
Re: how to break out early of a case ?
« Reply #205 on: May 29, 2025, 02:10:13 pm »
( No further reactions? Afraid of proper documentation....?)
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

jamie

  • Hero Member
  • *****
  • Posts: 6953
Re: how to break out early of a case ?
« Reply #206 on: May 29, 2025, 04:13:18 pm »
I tried to shift through the piles of consciousness of those making a case for how the Pascal vs the C selective statements work and got lost so excuse me if this was already stated.

 In "C", if things haven't change since the last time, I constructed Switch statements the CASE that matches gets executed as like in PASCAL but, in PASCAL the "BREAK" is automatically assumed somewhere in the statement unless a GOTO is executed out of the CASE (pascal), SWITCH (C).

 In 'C', without the use of BREAK it simply follows through the next "CASE" selection without actually performing a CASE test in 'C'. So, this means the coder needs to organize the code in such a way that it becomes serialized, like used in decoding or encoding Serial Data streams but it happens to work out flawlessly in most cases.

 In Pascal, you can also perform this task however, since the BREAK is naturally inherent in PASCAL the coder must use a GOTO to a place prior to the CASE statement start and also the coder must change the value of the switch being examine due to how the CASE in pascal works. This means while in a current case switch of PASCAL you must change this value prior to using the GOTO to force a retake on the PASCAL case system.

 All in all, you can force both to behave like each other, the C version is most likely more code efficient, but it must be fully understood by the coder to take advantage of it, whereas the Pascal version is safer for unexperienced C coders and will likely generate more code in the background to duplicate the follow through as in C. But what are we talking about here, Apples and oranges? I like both.



The only true wisdom is knowing you know nothing

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12264
  • FPC developer.
Re: how to break out early of a case ?
« Reply #207 on: May 29, 2025, 10:34:32 pm »
All in all, you can force both to behave like each other, the C version is most likely more code efficient, but it must be fully understood by the coder to take advantage of it, whereas the Pascal version is safer for unexperienced C coders and will likely generate more code in the background to duplicate the follow through as in C. But what are we talking about here, Apples and oranges? I like both.

I would rather say that the C version can be used for some rare fall through tricks, but pays for that by making optimization (reorganizing the order of evaluations) more complicated/require more analysis. And that is not even counting the accidental mistakes (that are not just by beginners, a minor mistake is easily made)

Since a optimizing compiler could change the goto from the end of a case to the next label into a representation equivalent to fallthrough, and at the same time C compiler could reorder more easily if it can detect fall through, with sufficient optimization (and that is not really the rocketscience kind) they are equivalent.

IMHO the whole fallthrough is a C apologist fallacy, people simply don't want to acknowledge that their "beloved" C could have gotten it wrong due to its macro assembler roots.

440bx

  • Hero Member
  • *****
  • Posts: 5466
Re: how to break out early of a case ?
« Reply #208 on: May 29, 2025, 10:44:50 pm »
IMHO the whole fallthrough is a C apologist fallacy, people simply don't want to acknowledge that their "beloved" C could have gotten it wrong due to its macro assembler roots.
I think the part they got wrong is to require "break" to prevent fall-through.  The fall-through feature itself is, often enough, very useful and when needed in Pascal, it complicates the code to implement it because Pascal doesn't provide a simple way of falling through.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12264
  • FPC developer.
Re: how to break out early of a case ?
« Reply #209 on: May 29, 2025, 11:01:38 pm »
IMHO the whole fallthrough is a C apologist fallacy, people simply don't want to acknowledge that their "beloved" C could have gotten it wrong due to its macro assembler roots.
I think the part they got wrong is to require "break" to prevent fall-through.  The fall-through feature itself is, often enough, very useful and when needed in Pascal, it complicates the code to implement it because Pascal doesn't provide a simple way of falling through.

A goto would be good enough for those cases. Fallthrough is not something brilliant. It is simply C showing its macro assembler pedigree where

Code: C  [Select][+][-]
  1. case 1:
  2. case 2:
  3.          break
  4.  

was apparently cheaper to code in the compiler then

Code: C  [Select][+][-]
  1. case 1,2:
  2.              break;
  3.  

If you don't believe me, read K&R. I have the 2nd edition, page 59: (the bold is my emphasis).

Quote from: k&r
...Falling through cases is a mixed blessing. On the positive side, it allows several cases to be attached to a single action. But it also implies that normally each case must end with a break...

and
Quote from: k&r
Falling through from one case to another is not robust, being prone to disintegration when the program is modified. With the exception of multiple labels for a single computation fall-throughs should be used sparingly and commented

So no grand algorithmic uplands. Just awkward early syntax in an language that probably should have been corrected later on, if the language hadn't been so frozen due to its ties with Unix and its source portability concepts. The rest, as I already said, is apologism.

P.s. personally I'm amazed they at least forced the case nodes to be constant expressions. Can you imagine the abuse a-la Duff's device that would have wrought ?
« Last Edit: May 29, 2025, 11:05:45 pm by marcov »

 

TinyPortal © 2005-2018