Main Content

MISRA C++:2023 Rule 18.3.2

An exception of class type shall be caught by const reference or reference

Since R2024b

Description

Rule Definition

An exception of class type shall be caught by const reference or reference.

Rationale

If a class type exception is caught by value, the exception object might be sliced. For instance:

class baseException(); 
class derivedException : public baseException {}; 

void foo() { 
	try { 
		//... 
		throw derivedException(); 
	} 
	catch (baseException e) { //slices the thrown exception 
		//... 
	} 
} 
When the catch block in foo() catches the derivedException object, you might expect the object to remain a derivedException object. Because the object is caught by value, it is sliced to a baseException object. Unintended object slicing risks unexpected code behavior at run time. To avoid object slicing, catch class type exceptions by reference or const reference.

Polyspace Implementation

Polyspace® flags catch statements where class type exceptions are caught by value.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <exception> 
#include <iostream> 

class baseException : public std::exception { 
public: 
	baseException() : exception() {} 
	const char* what() const noexcept(true) override { 
		return "Base Exception Object"; 
	} 
}; 

class derivedException : public baseException { 
public: 
	derivedException() : baseException() {} 
	const char* what() const noexcept(true) override { 
		return "Derived Exception Object"; 
	} 
}; 

class exampleException{}; 

void foo() { 
	try { 
		throw derivedException(); 
	} 
	catch (baseException e) { //Noncompliant 
		std::cout << e.what(); 
	} 
	catch (derivedException e) { //Noncompliant 
		std::cout << e.what(); 
	} 
	catch (exampleException e) { //Noncompliant 
	} 
	catch (baseException &e) { //Compliant 
		std::cout << e.what(); 
	} 
	catch (const baseException &e) { //Compliant 
		std::cout << e.what(); 
	} 
	catch (derivedException &e) { //Compliant 
		std::cout << e.what(); 
	} 
	catch (const derivedException &e) { //Compliant 
		std::cout << e.what(); 
	} 
} 

In this example, Polyspace flags the catch blocks that catches exception objects by value. For instance:

  • Catch blocks for exceptions of type baseException, derivedException, and exampleException are noncompliant because the thrown class type exception is caught by value. These blocks might slice the exception objects.

  • Catch blocks for exceptions of type baseException &, const baseException &, derivedException &, and const derivedException & are compliant because the class type exception is caught by reference or const reference.

Check Information

Group: Exception Handling
Category: Required

Version History

Introduced in R2024b