Main Content

CERT C++: INT50-CPP

Do not cast to an out-of-range enumeration value

Since R2023b

Description

Rule Definition

Do not cast to an out-of-range enumeration value.1

Polyspace Implementation

The rule checker checks for the issue Casting to out-of-range enumeration value.

Examples

expand all

Casting to out-of-range enumeration value

The issue Casting to out-of-range enumeration value occurs when you cast an arithmetic value to an enumeration but the arithmetic value is too big for the enumeration.

Whether an arithmetic value is too big for an enumeration depends on the underlying type of the enumeration:

  • For scoped enumerations, Polyspace® assumes that the underlying type is int.

  • For unscoped enumerations with a fixed underlying type, Polyspace assumes that the range of the enumeration is the same as the range of the underlying type.

  • For unscoped enumerations without a fixed underlying type, Polyspace assumes that the underlying type of the enumeration has the smallest possible bit-width that accommodates all the enumerators.

The signedness of the assumed underlying type follows the signedness of the enumerators.

Risk

The result of casting to an out-of-range enumeration value is unspecified for C++ version older than C++17. For C++17 and later, this operation results in undefined behavior. Such casts might compile correctly but result in unexpected or incorrect behavior.

Fix

To fix this issue, use any of these fixes:

  • Perform bound checking before the cast.

  • Use scoped enumerations.

  • Use unscoped enumerations with a fixed underlying type.

Example — Casting to Unscoped enum

In this example, the int variable value is cast to an the enum type myEnum. The unscoped enumeration myEnum does not have a fixed underlying type. Polyspace assumes that the range of myEnum is [0.. 3]. Because value is an integer, its range is wider than [0.. 3]. Because value can be out of range for myEnum, the static_cast operation can result in an unspecified value. Polyspace reports a violation on the operation.

The bound checking cannot prevent the out-of-range cast because the bound is checked after the cast operation.

enum myEnum {
  One,
  Two,
  Three
};
 
void foo(int value) {
  myEnum enum_val = static_cast<myEnum>(value); //Noncompliant
 
  if (enum_val < One || enum_val > Three) {
    // Handle error
  }
}
Correction — Check Bounds Before Casting

To fix this violation, perform the bound check before the cast.

enum myEnum {
  One,
  Two,
  Three
};
 
void foo(int value) {
  if (value < One || value > Three) {
    // Handle error
	return;
  }
  myEnum enum_val = static_cast<myEnum>(value); //Compliant
 
  
}
Correction — Use enum class

Fix this violation by using scoped enumerations. In this case, the range of myEnum is same as that of int and the cast is in range.

enum class myEnum {
  One,
  Two,
  Three
};
 
void foo(int value) {
  //..
  myEnum enum_val = static_cast<myEnum>(value); //Compliant
 
  
}
Correction — Use enum with Fixed Underlying Type

Fix this violation by using enum with fixed underlying type. In this case, the range of myEnum is the same as that of int and the cast is in range.

enum myEnum:int {
  One,
  Two,
  Three
};
 
void foo(int value) {
  //..
  myEnum enum_val = static_cast<myEnum>(value); //Compliant
 
  
}

Check Information

Group: 03. Integers (INT)

Version History

Introduced in R2023b


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.