Having a switch and its cases wholly encompassed by a control structure such as a try, @try,
catch, @catch, or a loop is perfectly acceptable. (try and catch are used hereafter to refer to
both variants.) It is also acceptable to have a goto and its target label wholly encompassed in a control structure.
What is not acceptable is using a goto or case to suddenly jump into the body of a try, catch,
Objective-C @finally, or loop structure. Tangling labels or switch blocks with other control structures results in code that
is difficult, if not impossible to understand. More importantly, when it compiles (some of these constructs won’t compile under ISO-conformant
compilers), it can lead to unexpected results. Therefore this usage should be strictly avoided.
This C++ code sample, which is also applicable to Objective-C if try and catch are converted to @try and
@catch, demonstrates jumping into a switch and into a try and catch :
Noncompliant code example
void f ( int32_t i )
{
if ( 10 == i )
{
goto Label_10; // Noncompliant; goto transfers control into try block
}
if ( 11 == i )
{
goto Label_11; // Noncompliant; goto transfers control into catch block
}
switch ( i )
{
case 1:
try
{
Label_10:
case 2: // Noncompliant; switch transfers control into try block
// Action
break;
}
catch ( ... )
{
Label_11:
case 3: // Noncompliant; switch transfers control into catch block
// Action
break;
}
break;
default:
{
// Default Action
break;
}
}
}
Compliant solution
void f ( int32_t i )
{
switch ( i )
{
case 1:
case 2:
// Action
break;
case 3:
// Action
break;
case 10:
default:
{
// Default Action
break;
}
}
try
{
if ( 2 == i || 10 == i)
{
// Action
}
}
catch ( ... )
{
if (3 == i || 11 == i)
{
// Action
}
}
}