Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fake switch or fake loop only to break

51 views
Skip to first unread message

Frederick Gotham

unread,
Jun 15, 2020, 5:45:11 PM6/15/20
to
[I have multi-posted this to comp.lang.c and comp.lang.c++]

Have you ever seen code written as follows?

if ( cond1 )
{
if ( cond2 )
{
if ( cond3 )
{
if ( cond4 )
{
DoSomething();
}
}
}
}


Well some people think that the above is very poorly written code, and they prefer it like this:


if ( !cond1 ) return;

if ( !cond2 ) return;

if ( !cond3 ) return;

if ( !cond4 ) return;

Do Something();


If you can't simply return from the function, and instead want to skip over a section of code, you could use 'goto':


if ( !cond1 ) goto Label_At_End;

if ( !cond2 ) goto Label_At_End;

if ( !cond3 ) goto Label_At_End;

if ( !cond4 ) goto Label_At_End;

Do Something();

Label_At_End:
;


Some programmers and some firms are very much against the use of 'goto'. In order to avoid using 'goto' today, I instead used a switch statement like this:

switch (true)
{
default:;

if ( !cond1 ) break;

if ( !cond2 ) break;

if ( !cond3 ) break;

if ( !cond4 ) break;

Do Something();
}


Another alternative would have been to use a 'do' loop as follows:


do
{
default:;

if ( !cond1 ) break;

if ( !cond2 ) break;

if ( !cond3 ) break;

if ( !cond4 ) break;

Do Something();
} while (false);


Does anyone else use fake switches and fake loops like this just to exploit the 'break' keyword?

Frederick Gotham

unread,
Jun 15, 2020, 5:47:01 PM6/15/20
to
On Monday, June 15, 2020 at 10:45:11 PM UTC+1, Frederick Gotham wrote:

> do
> {
> default:;


I copy-pasted the code from the fake 'switch' and forgot to remove the 'default'.

Lew Pitcher

unread,
Jun 15, 2020, 6:02:24 PM6/15/20
to
On June 15, 2020 17:58, Stefan Ram wrote:

> Frederick Gotham <cauldwel...@gmail.com> writes:
>>if ( cond1 )
>>{
>> if ( cond2 )
>> {
>> if ( cond3 )
>> {
>> if ( cond4 )
>> {
>> DoSomething();
>> }
>> }
>> }
>>}
>
> int main3() { if( cond4 )DoSomething(); }
> int main2() { if( cond3 )main3(); }
> int main1() { if( cond2 )main2(); }
> int main( ) { if( cond1 )main1(); }

if ((cond1) && (cond2) && (cond3) && (cond4)) DoSomething();

--
Lew Pitcher
"In Skills, We Trust"

Chris M. Thomasson

unread,
Jun 15, 2020, 6:04:12 PM6/15/20
to
On 6/15/2020 2:44 PM, Frederick Gotham wrote:
> [I have multi-posted this to comp.lang.c and comp.lang.c++]
>
> Have you ever seen code written as follows?
>
> if ( cond1 )
> {
> if ( cond2 )
> {
> if ( cond3 )
> {
> if ( cond4 )
> {
> DoSomething();
> }
> }
> }
> }
[...]


Yes. Way back in looking at some adventure games written in BASIC on my
Apple IIgs.

>

Christian Gollwitzer

unread,
Jun 16, 2020, 1:29:21 AM6/16/20
to
Am 15.06.20 um 23:44 schrieb Frederick Gotham:
> [I have multi-posted this to comp.lang.c and comp.lang.c++]
>
> Have you ever seen code written as follows?
>
> if ( cond1 )
> {
> if ( cond2 )
> {
> if ( cond3 )
> {
> if ( cond4 )
> {
> DoSomething();
> }
> }
> }
> }
>
>
> Well some people think that the above is very poorly written code, and they prefer it like this:
>
>
> if ( !cond1 ) return;
>
> if ( !cond2 ) return;
>
> if ( !cond3 ) return;
>
> if ( !cond4 ) return;
>
> Do Something();

This is how I'd do it. If the conditions do error checking, i.e.
checking that the input parameters are valid, instead of "return" it
could also be "throw."


> If you can't simply return from the function, and instead want to skip over a section of code, you could use 'goto':
>
>
> if ( !cond1 ) goto Label_At_End;
>
> if ( !cond2 ) goto Label_At_End;
>
> if ( !cond3 ) goto Label_At_End;
>
> if ( !cond4 ) goto Label_At_End;
>
> Do Something();
>
> Label_At_End:
> ;

This is how I do it in C due to lack of exceptions. After the label I
release the resources. But why should it not be possible to do
return/throw here in C++? Because there is more unrelated code after the
label? Usually it makes sense to put the whole thing into a function on
its own, and then you can return.


>
>
> Some programmers and some firms are very much against the use of 'goto'. In order to avoid using 'goto' today, I instead used a switch statement like this:
>
> switch (true)
> {
> default:;
>
> if ( !cond1 ) break;
>
> if ( !cond2 ) break;
>
> if ( !cond3 ) break;
>
> if ( !cond4 ) break;
>
> Do Something();
> }

Feels hackish.

Christian

David Brown

unread,
Jun 16, 2020, 3:14:39 AM6/16/20
to
On 15/06/2020 23:44, Frederick Gotham wrote:
> [I have multi-posted this to comp.lang.c and comp.lang.c++]
>
> Have you ever seen code written as follows?
>
> if ( cond1 )
> {
> if ( cond2 )
> {
> if ( cond3 )
> {
> if ( cond4 )
> {
> DoSomething();
> }
> }
> }
> }

How about :

if (cond1 && cond2 && cond3 && cond4) {
DoSomething();
}


>
>
> Well some people think that the above is very poorly written code, and they prefer it like this:
>
>
> if ( !cond1 ) return;
>
> if ( !cond2 ) return;
>
> if ( !cond3 ) return;
>
> if ( !cond4 ) return;
>
> Do Something();
>

That's good for some kind of tests. In particular, tests on the
parameters of a function followed by early exits are a popular style.
(Not everyone likes it - some people feel functions should only ever
have one exit.)

There is no single "best" method - it will depend on the code as well as
any style preferences or requirements for the project and team.

>
> If you can't simply return from the function, and instead want to skip over a section of code, you could use 'goto':
>
>
> if ( !cond1 ) goto Label_At_End;
>
> if ( !cond2 ) goto Label_At_End;
>
> if ( !cond3 ) goto Label_At_End;
>
> if ( !cond4 ) goto Label_At_End;
>
> Do Something();
>
> Label_At_End:
> ;
>

That's also a common idiom. It's not one I like - I don't find use for
gotos in my own code. But some people do.


>
> Some programmers and some firms are very much against the use of 'goto'. In order to avoid using 'goto' today, I instead used a switch statement like this:
>
> switch (true)
> {
> default:;
>
> if ( !cond1 ) break;
>
> if ( !cond2 ) break;
>
> if ( !cond3 ) break;
>
> if ( !cond4 ) break;
>
> Do Something();
> }
>

That would be a code review fail right away - it's an unnecessarily ugly
hack and an abuse of switch. Your "do {} while (false);" is much less
bad (omitting the "default:").

>
> Another alternative would have been to use a 'do' loop as follows:
>
>
> do
> {
> default:;
>
> if ( !cond1 ) break;
>
> if ( !cond2 ) break;
>
> if ( !cond3 ) break;
>
> if ( !cond4 ) break;
>
> Do Something();
> } while (false);
>
>
> Does anyone else use fake switches and fake loops like this just to exploit the 'break' keyword?
>

I've never felt the need.

Öö Tiib

unread,
Jun 16, 2020, 11:47:07 AM6/16/20
to
On Tuesday, 16 June 2020 00:45:11 UTC+3, Frederick Gotham wrote:
> [I have multi-posted this to comp.lang.c and comp.lang.c++]
>
> Have you ever seen code written as follows?

I think that variant is most cute:

if (not cond1 || not cond2 || not cond3 || not cond4)
return;

DoSomething();

But I dislike when someone puts up pull request where they
pointlessly transformed between whatever was there and what
is their favorite. It just results with massive diff
that hides what they actually did if anything.
So unless whatever they remodeled it into is specified in
coding standard of project as preferred I will complain.

Makis

unread,
Jun 16, 2020, 1:05:46 PM6/16/20
to
Am 15.06.2020 um 23:44 schrieb Frederick Gotham:
> Well some people think that the above is very poorly written code, and they prefer it like this:
>
>
> if ( !cond1 ) return;
>
> if ( !cond2 ) return;
>
> if ( !cond3 ) return;
>
> if ( !cond4 ) return;
>
> Do Something();

Very hard if you have to do some cleanup upon leaving

>
>
> If you can't simply return from the function, and instead want to skip over a section of code, you could use 'goto':
>
>
> if ( !cond1 ) goto Label_At_End;
>
> if ( !cond2 ) goto Label_At_End;
>
> if ( !cond3 ) goto Label_At_End;
>
> if ( !cond4 ) goto Label_At_End;
>
> Do Something();
>
> Label_At_End:
> ;
>
No comment!

> Some programmers and some firms are very much against the use of 'goto'. In order to avoid using 'goto' today, I instead used a switch statement like this:
>
> switch (true)
> {
> default:;
>
> if ( !cond1 ) break;
>
> if ( !cond2 ) break;
>
> if ( !cond3 ) break;
>
> if ( !cond4 ) break;
>
> Do Something();
> }
>

This is a misuse of switch statement

>
> Another alternative would have been to use a 'do' loop as follows:
>
>
> do
> {
> default:;
>
> if ( !cond1 ) break;
>
> if ( !cond2 ) break;
>
> if ( !cond3 ) break;
>
> if ( !cond4 ) break;
>
> Do Something();
> } while (false);
>
>
> Does anyone else use fake switches and fake loops like this just to exploit the 'break' keyword?
>

I use this a lot. Better than nested ifs. You can do a cleanup at the
end. And... it works for C too!

Marcel Mueller

unread,
Jun 16, 2020, 2:08:39 PM6/16/20
to
> Does anyone else use fake switches and fake loops like this just to exploit the 'break' keyword?

I prefer

do
{
...

break;
} while(true);

It basically defines two labels.
One to repeat the current block: continue,
and one after the current block: break.


It can also be useful to write

do
{
...

} while (fasle);

This is especially useful to escape from a nested switch statement with
continue.


But all of them are not always better than goto. It mainly helps to keep
code guidelines that prohibit the use of goto.

E.g. in case of CAS loops I prefer goto retry; since it is no loop in
the logical application flow.


Marcel

Christian Gollwitzer

unread,
Jun 16, 2020, 2:41:19 PM6/16/20
to
Am 16.06.20 um 19:05 schrieb Makis:
> Am 15.06.2020 um 23:44 schrieb Frederick Gotham:
>> Well some people think that the above is very poorly written code, and
>> they prefer it like this:
>>
>>
>> if ( !cond1 ) return;
>>
>> if ( !cond2 ) return;
>>
>> if ( !cond3 ) return;
>>
>> if ( !cond4 ) return;
>>
>> Do Something();
>
> Very hard if you have to do some cleanup upon leaving

On the contrary, very easy. Use RAII and the compiler does the right
cleanup in the right order. In real cases, I allocate resources in
between the different conditions. That means a lot of conditions for the
cleanup sequence, too, (necessary in C without ++) unless you use RAII
consequently, which leaves this to the compiler.

Christian



Juha Nieminen

unread,
Jun 17, 2020, 2:44:12 AM6/17/20
to
David Brown <david...@hesbynett.no> wrote:
> How about :
>
> if (cond1 && cond2 && cond3 && cond4) {
> DoSomething();
> }

Only possible if there isn't any other code inside those conditionals.
Like:

if(!cond1) return;
doSomething();
if(!cond2) return;
doSomethingElse();
if(!cond3) return;
andSomethingOther();
if(!cond4) return;
theFinalThing();
0 new messages