C and C++


LANG.STRUCT.SW.SWNEE : switch With Non-enum Expression

Summary

A switch whose cases suggest the code might be cleaner if an enumeration were employed, instead of raw integers.

Specifically, a switch statement for which all of the following are true.

For the sake of this warning class, the label density of a switch statement is computed as:

100 × LabelDensity = LabelCount/(maxLabelValue - minLabelValue + 1)

where

Properties

Class Name switch With Non-enum Expression
Significance style
Mnemonic LANG.STRUCT.SW.SWNEE
Categories
AUTOSARC++14 AUTOSARC++14:A7-2-5 Enumerations should be used to represent sets of related named constants.
CWE CWE:1106 Insufficient Use of Symbolic Constants
CERT-C CERT-C:DCL06-C Use meaningful symbolic constants to represent literal values
JSF++ JSF++:148 Enumeration types shall be used instead of integer types (and constants) to select from a limited series of choices.
Availability Available for C and C++.
Enabling Checks for this warning class are disabled by default, and require the unnormalized C ASTs for the project. To enable them, add the following WARNING_FILTER rule and RETAIN_UNNORMALIZED_C_AST specification to the project configuration file.
RETAIN_UNNORMALIZED_C_AST = Yes
WARNING_FILTER += allow class="switch With Non-enum Expression"
Note that retaining the unnormalized ASTs will increase the disk space used to store the project representation, and may make the analysis take longer.

Example

int badlang_struct_sw_swnee( int myint ) {
    switch( myint ){ /* 'switch With Non-enum Expression' warning issued here
                      * - controlling expression has int type
                      * - has 3 non-default, non-range, non-character-constant case labels
                      *   (== threshold from factory setting of SWITCH_LABEL_CARDINALITY_THRESHOLD)
                      * - label density is (label count)/len(label range) = 3/3 = 1
                      *   (above threshold from factory setting of SWITCH_LABEL_DENSITY_THRESHOLD)
                      */
    case 1:
    case 2:
    case 3:
        return 0;
    default:
        return 1;
    }
}

int fewer_cases_int_switch( int myint ) {
    switch( myint ) {                 /* only has 2 non-default, non-range, labels
                                       * - below threshold from factory setting of
                                       *  SWITCH_LABEL_CARDINALITY_THRESHOLD */
    case 1:
    case 2:
        return 0;
    default:
        return 1;
    }
}

int sparser_cases_int_switch( int myint ) {
    switch( myint ) {                 /* label density = 3/(300-100+1) =~ 1.5%
                                       *  - below threshold from factory setting of
                                       * SWITCH_LABEL_DENSITY_THRESHOLD */
    case 100:
    case 200:
    case 300:
        return 0;
    default:
        return 1;
    }
}

typedef enum {
    CASE1 = 1,
    CASE2,
    CASE3,
    CASE4
} CASE_ENUM;

int enum_control( CASE_ENUM mycaseenum ) {
    switch( mycaseenum ) {            /* controlling expression has enumeration type */
    case CASE1:
    case CASE2:
    case CASE3:
        return 0;
    default:
        return 1;
    }
}

Relevant Configuration File Parameters

The following configuration file parameters affect checks for this warning class.