-
Type:
Code Smell Detection
-
Status: Active
-
Resolution: Unresolved
-
Labels:
-
Message:
-
Default Severity:Blocker
-
Impact:High
-
Likelihood:High
-
Default Quality Profiles:Sonar way, MISRA C++ 2008 recommended
-
Covered Languages:C, C++, Objective-C
-
Remediation Function:Constant/Issue
-
Constant Cost:15min
-
CERT:MSC20-C.
-
MISRA C++ 2008:15-0-3
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 } } }
See
- MISRA C++:2008, 15-0-3 - Control shall not be transferred into a try or catch block using goto or switch statement
- CERT, MSC20-C. - Do not use a switch statement to transfer control into a complex block