On Thursday, 8 September 2022 at 22:47:33 UTC, Walter Bright wrote:
> To be fair, nested functions along with function inlining has eliminated many of the reasons that I use gotos.
Another reason for gotos is for ways of exiting loops without having to set flags that later control the flow.
Yeah, there's this code from dmd/dsymbolsem.d:
if (FuncDeclaration func = sc.parent.isFuncDeclaration())
{
tm.symtab = func.localsymtab;
if (tm.symtab)
{
// Inside template constraint, symtab is not set yet.
goto L1;
}
}
else
{
tm.symtab = sc.parent.isScopeDsymbol().symtab;
L1:
assert(tm.symtab);
tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
tm.symtab.insert(tm);
}
You can write it as:
(){
if (FuncDeclaration func = sc.parent.isFuncDeclaration())
{
tm.symtab = func.localsymtab;
if (!tm.symtab) return;
// Inside template constraint, symtab is not set yet.
}
else
tm.symtab = sc.parent.isScopeDsymbol().symtab;
//L1:
assert(tm.symtab);
tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
tm.symtab.insert(tm);
}();
I'd prefer to write it as:
switch
{
if (FuncDeclaration func = sc.parent.isFuncDeclaration())
{
tm.symtab = func.localsymtab;
if (!tm.symtab) break;
// Inside template constraint, symtab is not set yet.
}
else
tm.symtab = sc.parent.isScopeDsymbol().symtab;
//L1:
assert(tm.symtab);
tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
tm.symtab.insert(tm);
}
Where switch
works like switch(0) default:
today.
Using the function literal call means you can't return from the containing function, which may be needed.