Вебинар: C# разработка и статический анализ: в чем практическая польза? - 18.11
Решил записать один момент, связанный с виртуальными функциями, а то боюсь, что потом его забуду и случайно вновь вернусь к этому вопросу :).
В анализаторе Viva64 есть диагностика ошибок, возникающих в 64-битном коде, когда у виртуальных функций изменяется тип аргумента. Подробнее это описано в документации к продукту здесь: V301.
Вот пример кода, где анализатор выдаст эти предупреждения:
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;
}
В 32-битном режиме на печать будет выдано "3 2", а в 64-битном режиме "1 4". Ошибки в данном коде успешно диагностируются анализатором Viva64. Но недавно меня посетила мысль, что необходимо диагностировать не только изменяющиеся аргументы виртуальных функций, но и возвращаемый аргумент. В голове у меня возник следующий пример, который следует диагностировать как ошибочный:
class A
{
public:
virtual int x() {};
};
class B : public A
{
public:
ptrdiff_t x() {};
};
К счастью такой вариант в 64-битном режиме просто не скомпилируется и соответственно не возникнет ошибки связанной с изменением поведения кода. Компилятор Visual C++ выдает ошибку:
error C2555: 'B::x': overriding virtual function return type differs and is not covariant from 'A::x' : see declaration of 'A::x'
После проделанного эксперимента, я начал припоминать, что, кажется, уже проделывал подобное исследование. И соответственно диагностика по возвращаемым значениям не требуется. Подумав, я решил сделать эту запись в блог, чтобы через год в третий раз не вернуться к этому вопросу. :)
Рассмотрим последний момент, связанный с диагностикой функций, где отличается как аргумент, так и возвращаемый тип:
class A
{
public:
virtual int x(int) { return 1; }
};
class B : public A
{
public:
ptrdiff_t x(ptrdiff_t) { return 2; } //V301
};
Данный код компилируется и содержит ошибку. Анализатор Viva64 корректно разбирается в подобной ситуации и предупреждает, что аргумент изменяет свой тип в 64-битной системе. После исправления этой ошибки, компилятор откажется компилировать код и будет исправлена вторая ошибка - тип возвращаемого аргумента.
0