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.

>
>
>
V1101. Changing the default argument of…
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

V1101. Changing the default argument of a virtual function parameter in a derived class may result in unexpected behavior.

01 Aoû 2023

The analyzer has detected a virtual function that has a parameter with a default argument. Default arguments are defined in the base and derived classes; their values are different. Changing the default argument of a virtual function parameter in this way is not an error, but it can lead to unexpected results when using these classes.

Take a look at the example:

struct Base
{
  virtual void foo(int i = 0) const noexcept
  {
    std::cout << "Base::foo() called, i = " << i << std::endl;
  }
};

struct Derived : Base
{
  void foo(int i = 10) const noexcept override
  {
    std::cout << "Derived::foo() called, i = " << i << std::endl;
  }
};

In the 'Base' class, the 'foo' virtual function is defined with one 'i' parameter that has a default argument of '0'. In the 'Derived' class, which is derived from 'Base', the 'foo' virtual function is overridden and the default argument of the 'i' parameter is changed to '10'.

Let's see what issues such overriding may cause. Let's say we use the code as follows:

int main()
{
  Derived obj;
  Base *ptr = &obj;
  ptr->foo();
}

The 'main' function will return an unexpected string — "Derived::foo() called, i = 0". When forming the 'foo' function call, a compiler takes the static type of an object under the 'ptr' pointer — 'Base'. Therefore, the default argument of '0' from the base class is substituted in the function call. At the same time, the 'ptr' variable actually points to an object of the 'Derived' type. So, the virtual function from the derived class is executed.

To avoid this kind of behavior, we recommend using one of the following strategies:

  • don't use default arguments in virtual functions;
  • define the default argument of the virtual function parameter only in the base class.

Here's the correct example:

struct Base
{
  virtual void foo(int i = 0) const noexcept
  {
    std::cout << "Base::foo() called, i = " << i << std::endl;
  }
};

struct Derived : Base
{
  void foo(int i) const noexcept override
  {
    std::cout << "Derived::foo() called, i = " << i << std::endl;
  }
};

Note. The analyzer does not issue any warnings for the following code:

struct Base
{
  virtual void foo(int i = 0) const noexcept
  {
    std::cout << "Base::foo() called, i = " << i << std::endl;
  }
};

struct Derived : Base
{
  void foo(int i = 0) const noexcept override
  {
    std::cout << "Derived::foo() called, i = " << i << std::endl;
  }
};

However, we do not recommend writing such code because it is more difficult to maintain.

This diagnostic is classified as: