Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter
to the top
close form

Remplissez le formulaire ci‑dessous en 2 étapes simples :

Vos coordonnées :

Étape 1
Félicitations ! Voici votre code promo !

Type de licence souhaité :

Étape 2
Team license
Enterprise licence
** En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité
close form
Demandez des tarifs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
La licence PVS‑Studio gratuit pour les spécialistes Microsoft MVP
close form
Pour obtenir la licence de votre projet open source, s’il vous plait rempliez ce formulaire
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
I am interested to try it on the platforms:
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
check circle
Votre message a été envoyé.

Nous vous répondrons à


Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

>
>
>
V746. Object slicing. An exception shou…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Micro-Optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V746. Object slicing. An exception should be caught by reference rather than by value.

19 Jan 2016

The analyzer detected a potential error that has to do with catching an exception by value. It is much better and safer to catch exceptions by reference.

Catching exceptions by value causes two types of issues. We'll discuss each of them separately.

Issue No. 1. Slicing.

class Exception_Base {
....
virtual void Print() { .... }
};
class Exception_Ex : public Exception_Base { .... };
try
{
  if (error) throw Exception_Ex(1, 2, 3);
}
catch (Exception_Base e)
{
  e.Print();
  throw e;
}

2 classes are declared here: an exception of a base type and an extended exception derived from the first one.

An extended exception is generated. The programmer wants to catch it, print its information, and then re-throw it.

The exception is caught by value. It means that a copy constructor will be used to create a new object, 'e', of type Exception_Base, and it will lead to 2 errors at once.

Firstly, some of the information about the exception will get lost; everything stored in Exception_Ex won't be available anymore. The virtual function Print() will only allow printing the basic information about the exception.

Secondly, what will be re-thrown is a new exception of type Exception_Base. Therefore, the information passed on will be sliced.

The fixed version of that code is as follows:

catch (Exception_Base &e)
{
  e.Print();
  throw;
}

Now the Print() function will print all the necessary information. The "throw" statement will re-throw the already existing exception, and the information won't get lost (sliced).

Issue No. 2. Changing a temporary object.

catch (std::string s)
{
  s += "Additional info";
  throw;
}

The programmer wants to catch the exception, add some information to it, and re-throw it. The problem here is that it is the 's' variable that gets changed instead while the "throw;" statement re-throws the original exception. Therefore, the information about the exception won't be changed.

Correct code:

catch (std::string &s)
{
  s += "Additional info";
  throw;
}

The pros of catching exceptions by reference are discussed in the following topics:

This diagnostic is classified as:

  • CERT-ERR61-CPP

You can look at examples of errors detected by the V746 diagnostic.