[Proposal]: Labeled break and continue Statements
#9876
Replies: 13 comments 78 replies
-
|
The proposal looks good to me. I strongly support it. One could possibly consider an even more flexible mechanism allowing @CyrusNajmabadi Your current code examples always have the label on the same line as the |
Beta Was this translation helpful? Give feedback.
-
|
As stated in the discussion that was closed: I want to be able to label loops and But I'm not sure I like that adding a label to allow I'd rather have separate syntax so that I can clearly see if a label is for My favorite would be: restart:
for outer: (int x = 0; x < xMax; x++)
{
for (int y = 0; y < yMax; y++)
{
if (ShouldSkipRest(x, y))
continue outer;
if (ShouldExitAll(x, y))
break outer;
if (ShouldStartFromScratch())
goto restart;
}
}where But if this is a non-issue to everybody else, I'm happy to swallow my syntax concerns if that means we get the feature, which I strongly support. |
Beta Was this translation helpful? Give feedback.
-
|
I'm somehow concerned about the position of the label. The syntax is currently valid and the label is placed before the start of the loop. |
Beta Was this translation helpful? Give feedback.
-
|
It feels so weird seeing this be proposed again. I was the original proposer of this feature almost a decade ago, wild to think that we still don't have some form of it after all this time. Anyway I still support this, though would like the ability to break with a number in addition to label, like my original proposition. But I understand the downsides of that particular implementation. |
Beta Was this translation helpful? Give feedback.
-
|
I quite liked the suggestion of: for (outer: var y = 0; y < 10; y++)
{
for (inner: var x = 0; x < 10; x++)
{
if (condition)
{
continue outer;
}
}
}
// Or
foreach (outer var item in items)
{
// ...
}This makes it distinct from |
Beta Was this translation helpful? Give feedback.
-
|
Whatever syntax is chosen, I think it's a good feature. I often need to break/continue nested loops (for work code and AoC fun code). Using a for (outer: var y = 0; y < 10; y++)
{
var skip = false;
for (inner: var x = 0; x < 10; x++)
{
if (condition)
{
skip = true;
break;
}
// Whatever processing you are doing
}
if (skip)
{
continue;
}
// The code you wanted to skip.
}Becomes: for (outer: var y = 0; y < 10; y++)
{
for (inner: var x = 0; x < 10; x++)
{
if (condition)
{
continue outer;
}
// Whatever processing you are doing
}
// The code you wanted to skip.
} |
Beta Was this translation helpful? Give feedback.
-
|
I don't really see why C# should have a dedicated feature for a rare specific case that is really no better than And the only motivation is a weird belief based on a 50 years old statement which was made in a drastically different programming environment. Just do an official statement that "goto is not considered harmful" and it's useful for cases exactly like this (and some other rare clever control flow tricks). Job done. |
Beta Was this translation helpful? Give feedback.
-
|
I have read the specification and the comments in this discussion, and I see several possible ways to implement such a named-loop mechanism. 1. Classic prefix label (
|
Beta Was this translation helpful? Give feedback.
-
|
I like it. Now do it for switch too. |
Beta Was this translation helpful? Give feedback.
-
|
how about breaking switch case? using System;
switch (1)
{
case 0:
goto case 1; // valid
case 1:
Console.WriteLine("🌄");
break;
case 2:
for(;;)
{
do
{
while (true)
{
break case 2; // breaking switch case by break '...';
}
}
while (true);
}
break;
} |
Beta Was this translation helpful? Give feedback.
-
|
@CyrusNajmabadi - One could also consider extending this to MAINIF:
if (cond1)
{
// stuff
if (cond2)
{
// stuff
if (cond3)
// stuff
else
break MAINIF;
}
}You get the idea, there are ways to avoid the need for this, but it might be worth considering... |
Beta Was this translation helpful? Give feedback.
-
|
What's intended for the following? a: b: while (true) break a;
// 1 2 3 4By the parsing rules, (
The text says
The "labeled statement" can be read as the If the intention is for it to fail compiling, the current text is fine. (Is re-nesting labels done during refactoring? I don't know.) If the intention is for it to compile, the current text should be edited to clarify the meaning of "labeled statement" to recursively reach for |
Beta Was this translation helpful? Give feedback.
-
|
FWIW, when I encounter this situation today, I don't use a goto or a flag, I just extract the nested statements to local function. ResultType? result = null;
foreach (var x in coll1)
{
foreach (var y in coll2)
{
result = Find(x, y);
if (result != null)
{
// Want to break out of all of this and use the result.
}
}
}
Use(result);If there's a certain spot after those nested constructs I want to get to, I can simply // Extract a local function:
var result = Search();
Use(result);
ResultType? Search()
{
foreach (var x in coll1)
{
foreach (var y in coll2)
{
result = Find(x, y);
if (result != null)
return result;
}
}
return null;
}Since capture in local functions tends to be pretty efficient and seamless, making such a change doesn't usually require refactoring the code very much. It also has a natural tendency to prevent methods from getting too sprawling with nested conditional constructs which we are jumping out of relatively complex ways. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Labeled
breakandcontinueStatementsbreakandcontinueStatements #9875Summary
Allow
breakandcontinuestatements to optionally specify a label that identifies which loop orswitchstatement to target, enabling cleaner control flow in nested constructs without requiring
gotostatements.For example:
Note: the label (
outer:) is itself not special or new. It is the existinglabeled-statementalready present in the language. All that changes is that when these label loops (andswitch), then theloop/switchis now able to be the target of acontinue x;/break x;statement, instead of those targeting the immediately inner construct.Beta Was this translation helpful? Give feedback.
All reactions