Main Content

MISRA C++:2008 Rule 15-3-5

A class type exception shall always be caught by reference

Description

Rule Definition

A class type exception shall always be caught by 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 runtime. 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 R2013b