Вызывает ли метод базового класса шаблона без предоставления аргументов шаблона неопределенное поведение?

Я работаю над многоплатформенным кодом (Windows, Linux и Mac), написанным на C ++. Сегодня мне пришлось найти проблему, которая возникла только в Windows, и похоже, что это проблема компилятора. Класс с несколькими базовыми классами вызывает метод базового класса, но при этом передается неправильное значение.

Я написал короткий пример C ++, чтобы воспроизвести эту проблему:

#include <stdio.h>class base1
{
public:
int x;

base1(int x):x(x)
{
printf("%s(): this=%p x=%d\n", __FUNCTION__, this, x);
}

void printx()
{
printf("%s(): this=%p x=%d\n", __FUNCTION__, this, x);
}

void print()
{
printf("%s(): this=%p\n", __FUNCTION__, this);
printx();
}

};

template <class T>
class base2
{
public:
int y;

base2(int y):y(y)
{
printf("%s(): this=%p y=%d\n", __FUNCTION__, this, y);
}

void printy()
{
printf("%s(): this=%p y=%d\n", __FUNCTION__, this, y);
}

void print()
{
printf("%s(): this=%p\n", __FUNCTION__, this);
printy();
}
};

class derived: public base1, public base2<derived>
{
public:
int z;

derived()
: base1(1)
, base2(2)
, z(3)
{
printf("%s(): this=%p z=%d\n", __FUNCTION__, this, z);
}

void printz()
{
printf("%s(): this=%p z=%d\n", __FUNCTION__, this, z);
}

void print()
{
printx();
base1::printx();
base1::print();

printf("-----\n");

printy();
base2::printy();    // <--- this call does not work with vs2005
base2::print();     // <--- and this call doesn't work, too.
base2<derived>::printy();
base2<derived>::print();

printf("-----\n");

printz();
}
};

int main(int argc, char *argv[])
{
derived d;

printf("-----\n");

d.print();
}

Код компилируется без каких-либо предупреждений в Windows (с использованием vs2005 и vs2010), Linux (g ++ (Gentoo 6.4.0-r1 p1.3) 6.4.0) и MacOS (Apple LLVM версии 8.1.0 (clang-802.0.42)) ,

Код должен всегда печатать x = 1, y = 2 или z = 3.

Но скомпилированный исполняемый файл vs2005 показывает y = 3 для вызовов base2 :: printy () и base2 :: print ().

base1::base1(): this=0018FF3C x=1
base2<class derived>::base2(): this=0018FF40 y=2
derived::derived(): this=0018FF3C z=3
-----
base1::printx(): this=0018FF3C x=1
base1::printx(): this=0018FF3C x=1
base1::print(): this=0018FF3C
base1::printx(): this=0018FF3C x=1
-----
base2<class derived>::printy(): this=0018FF40 y=2
base2<class derived>::printy(): this=0018FF44 y=3 <--------
base2<class derived>::print(): this=0018FF44
base2<class derived>::printy(): this=0018FF44 y=3 <--------
base2<class derived>::printy(): this=0018FF40 y=2
base2<class derived>::print(): this=0018FF40
base2<class derived>::printy(): this=0018FF40 y=2
-----
derived::printz(): this=0018FF3C z=3

Вызов работает, как и ожидалось, когда base2 является обычным классом, а не шаблоном класса.

Поскольку base2 является шаблоном класса, полное имя базового класса — не base2, а base2<полученный>, Тем не менее, ни один компилятор не жалуется на отсутствующий аргумент шаблона, но vs2005 тихо генерирует код, передавая неверный указатель this в вызываемый метод.

Вот мой вопрос:

Это «просто» ошибка компилятора в vs2005 или это неопределенное поведение, на которое не жалуется ни один компилятор?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector