>
>
>
Peculiarities of virtual functions

Andrey Karpov
Articles: 643

Peculiarities of virtual functions

I decided to describe one thing related to virtual functions because I am afraid I can forget it and return to this question once again later :).

Viva64 analyzer provides diagnosis of errors occurring in 64-bit code when a virtual function's argument changes its type. It is described in detail in the documentation on the product here: V301.

Here is an example when the analyzer generates these warnings:

class A
{
public:
  virtual int x(unsigned) { return 1; }
  virtual int y(__int64) { return 2; }
};
class B : public A
{
public:
  int x(size_t) { return 3; } //V301
  int y(ptrdiff_t) { return 4; } //V301
};
void Use()
{
  A *p = new B;
  cout << p->x(1) << " " << p->y(1) << endl;
  delete p;
}

In 32-bit mode, "3 2″ is printed while in 64-bit mode it is "1 4″. The errors in this code are successfully diagnosed by Viva64 analyzer. But an idea has stricken me recently that one should diagnose not only the changing arguments of virtual functions but the returned argument as well. I invented an example to be diagnosed as incorrect:

class A
{
public:
  virtual int x() {};
};
class B : public A
{
public:
  ptrdiff_t x() {};
};

Fortunately, this example simply will not compile in 64-bit mode and therefore no error related to a change of code behavior will appear. Visual C++ compiler generates an error message:

error C2555: 'B::x': overriding virtual function return type differs and is not covariant from 'A::x' : see declaration of 'A::x'

After this experiment I came to recalling that I seemed to have undertaken such an investigation before. So, there is no need in diagnosis of returned values. On thinking it over I decided to make a post in the blog in order not to come to this question for the third time a year later :)

Let us consider the last thing related to diagnosis of functions where both the argument and the returned type are different:

class A
{
public:
  virtual int x(int) { return 1; }
};
class B : public A
{
public:
  ptrdiff_t x(ptrdiff_t) { return 2; } //V301
};

This code does compile and has an error. Viva64 analyzer correctly makes it out and warns that the argument changes its type in a 64-bit system. After fixing this error the compiler refuses to compile the code and thus we can correct the second error - the returned argument's type.