Еще одна ошибка компилятора |
Здравствуйте, гость ( Вход | Регистрация )
Еще одна ошибка компилятора |
LuckLess |
19.10.2007, 10:47
Сообщение
#1
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
нуу.. опять начну с кода...
ну... вопервых почему этот код превельный.. static_cast<T*> должен сработать т.к. Цитата An rvalue of type “pointer to cv1 B,” where B is a class type, can be converted to an rvalue of type “pointer to cv2 D,” where D is a class derived (clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is not a virtual base class of D. самое сложное тут ATemplateBase::foo (); фактически такой вызов должен срботать т.к. есть такая штука как injected class name Цитата A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name. Цитата In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. Цитата Like normal (non-template) classes, class templates have an injected-class-name (clause 9). The injected-class-name can be used with or without a template-argument-list.When it is used without a template-argument-list, it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. так что ATemplateBase::foo (); нормальный вызов т.к. ATemplateBase это injected class name который можно использовать без шаблонных параметров. Вот.. собстно эффект от этого кода... в 8-й студии все очень плохо... переменная devilsNumber зачемто равно 666 ))). Одна из гцц нескомпилировала это дело.. что тоже плохо.. но заметно лучше чем результат студии как избавится от этого...? просто использовать injected-class-name с шаблонными параметрами. ATemplateBase<VS8ErrorClass>::foo (); техника такого статик каста прменяется во многих ATL-ых базовых классах.. и бывает краайне неудобно вызывать их метод полностью выписывая шаблонные параметры, так как их там часто очень много ждем второго сервис пака к студии?)) |
|
|
Tonal |
6.12.2007, 10:02
Сообщение
#2
|
Активный участник Группа: Участник Сообщений: 452 Регистрация: 6.12.2007 Из: Новосибирск Пользователь №: 34 Спасибо сказали: 69 раз(а) Репутация: 17 |
Такое и не должно компилироваться, из за
Здесь, по стандарту, должна быть явная классификация шаблона. У VC это довольно старая бага. Там таких полно: я когда их движёк регэкспов (гретту) попробывал использовать под gcc там подобные глюки пачками сыпались. А часто и более замысловатые. Эта та проблема довольно просто решается:
P.S. ошибка, которая вылезает в VC8 похоже связана не с этим а с выравниванием - где то он похоже путается. Если EatMe убрать из предков, что получится? А если поменять его местами с ATemplateBase? Сообщение отредактировал Tonal - 6.12.2007, 10:06 |
|
|
LuckLess |
7.12.2007, 11:32
Сообщение
#3
|
Студент Группа: Новичок Сообщений: 31 Регистрация: 10.10.2007 Пользователь №: 8 Спасибо сказали: 0 раз(а) Репутация: 0 |
P.S. ошибка, которая вылезает в VC8 похоже связана не с этим а с выравниванием - где то он похоже путается. Если EatMe убрать из предков, что получится? А если поменять его местами с ATemplateBase? Студия просто прибавляет двойное смещение к this-у для базового класса зачемто. Смотрел в асме даже Если базовый класс будет первыйм то двойное смещение будет 0 == 0*2 и все будет ок |
|
|
Tonal |
7.12.2007, 11:52
Сообщение
#4
|
Активный участник Группа: Участник Сообщений: 452 Регистрация: 6.12.2007 Из: Новосибирск Пользователь №: 34 Спасибо сказали: 69 раз(а) Репутация: 17 |
Зачем прибавляет - понятно - в ATemplateBase указатель this смещён относительно VS8ErrorClass.
Почему дважды - тоже понятно - первый раз - смещение ATemplateBase относительно обшего, второй смещение i относительн ATemplateBase в общем. Формально всё правильно, ведь sizeof любого класса > 0 и равен текущему выравниванию. Ошибается оно, похоже на "оптимизации базовых классов": стандартом разрешено не увеличивать размер в случае наследования от "пустого" класса. Пустым будет класс не содержащий данных членов, виртуальных функций и виртуального наследования не в себе не в своих предках. Похоже эта оптимизация производиться, но не во всех случаях корректно отрабатывают преобразования для this. Проверить это можно поиграв размерами и пустотой классов ATemplateBase и EatMe Ну и обход понятен, если так- добавить фиктивный член в ATemplateBase. |
|
|
Текстовая версия | Сейчас: 27.12.2024, 11:40 |