Для бешенной собаки 7 верст не крюк...
От: denisko http://sdeniskos.blogspot.com/
Дата: 17.11.09 11:55
Оценка:
или зарядко для мозгов.
Нарвался на распространенную ошибку, но в интересной обертке.
Предыстория. Есть проект, который писался на билдере, сейчас пишется на студии (ну и просто стараемся сделать достаточно переносимым). Есть структура размер которой, добавляя поля, менять нельзя, поэтому cделали такой костыль
#define DECLARE_PROPERTY_PROXY_ACESS(PropertyBase,Type, fnRead, fnWrite, Name)\
struct Property_##Name:public  PropertyBase(Type)\
{\
   __inline Property_##Name(PropertyHolder* parent):\
   m_parent(parent)\
   {\
      ;\
   }\
   __inline Type operator = (Type val)\
   {\
      m_parent->fnWrite(val);\
      return m_parent->fnRead();\
   }\
   __inline operator Type()\
   {\
     return m_parent->fnRead();\
   }\
private:\
   PropertyHolder* m_parent;\
};

т.е. структурко принимает на вход указатель на класс, делает с ним какие-то операции, и мимикрирует под нужный результат.
следующий код, по понятным причинам, вызывает падение (prev->Right() возвращает структуру подобную верхней)
currentRange.first = prev != NULL ? prev->Right() : 0;

Внимание вопрос: почему
З.ы. сегодня мне чуть не набили мордо, почувствовал себя автором "счастливой отладки".
<Подпись удалена модератором>
Re: Для бешенной собаки 7 верст не крюк...
От: 0xDEADBEEF Ниоткуда  
Дата: 17.11.09 13:00
Оценка:
Здравствуйте, denisko, Вы писали:


D>Внимание вопрос: почему

Потому что какой-то дятлъ не сделат конструктор для пропертей explicit-ным.
А по поводу условного оператора и того, как он вольно обращается с типами, курим стандарт, параграф 5.16

D>З.ы. сегодня мне чуть не набили мордо, почувствовал себя автором "счастливой отладки".

Есть за что
__________
16.There is no cause so right that one cannot find a fool following it.
Re: Для бешенной собаки 7 верст не крюк...
От: A13x США  
Дата: 17.11.09 13:02
Оценка:
Здравствуйте, denisko, Вы писали:

D>...


ошибка в приоритете операторов? Или fnRead вернула NULL?
кстати, __inline в коде выше бесполезен, функции реализованные по месту объявления и так считаются компилятором как inline.
Re: Для бешенной собаки 7 верст не крюк...
От: Caracrist https://1pwd.org/
Дата: 17.11.09 20:48
Оценка:
Здравствуйте, denisko, Вы писали:

D>или зарядко для мозгов.

D>Нарвался на распространенную ошибку, но в интересной обертке.
D>Предыстория. Есть проект, который писался на билдере, сейчас пишется на студии (ну и просто стараемся сделать достаточно переносимым). Есть структура размер которой, добавляя поля, менять нельзя, поэтому cделали такой костыль
D>
D>#define DECLARE_PROPERTY_PROXY_ACESS(PropertyBase,Type, fnRead, fnWrite, Name)\
D>struct Property_##Name:public  PropertyBase(Type)\
D>{\
D>   __inline Property_##Name(PropertyHolder* parent):\
D>   m_parent(parent)\
D>   {\
D>      ;\
D>   }\
D>   __inline Type operator = (Type val)\
D>   {\
D>      m_parent->fnWrite(val);\
D>      return m_parent->fnRead();\
D>   }\
D>   __inline operator Type()\
D>   {\
D>     return m_parent->fnRead();\
D>   }\
D>private:\
D>   PropertyHolder* m_parent;\
D>};
D>

D>т.е. структурко принимает на вход указатель на класс, делает с ним какие-то операции, и мимикрирует под нужный результат.
D>следующий код, по понятным причинам, вызывает падение (prev->Right() возвращает структуру подобную верхней)
D>
D>currentRange.first = prev != NULL ? prev->Right() : 0;
D>

D>Внимание вопрос: почему
Проблема в отсутствии референсов... Запускается сначала конструктор для параметра оператора равно, но чтобы передать ему данные нужно использовать оператор Type, однако там тоже не реф. и он снова пытается запустить конструктор и вызывает оператор равно у инстанса полученного из fnRead().
Скорее всего улетает в переполнение стёка.
D>З.ы. сегодня мне чуть не набили мордо, почувствовал себя автором "счастливой отладки".
~~~~~
~lol~~
~~~ Single Password Solution
Re[2]: Для бешенной собаки 7 верст не крюк...
От: denisko http://sdeniskos.blogspot.com/
Дата: 18.11.09 13:24
Оценка:
Здравствуйте, Caracrist, Вы писали:

C>Проблема в отсутствии референсов... Запускается сначала конструктор для параметра оператора равно, но чтобы передать ему данные нужно использовать оператор Type, однако там тоже не реф. и он снова пытается запустить конструктор и вызывает оператор равно у инстанса полученного из fnRead().

0xDEADBEEF ответил правильно. Я дотумкал только когда ассемблер посмотрел. Век живи век учись. Я не смотрел при полной оптимизации может по другому себя повести, а может и нет.
<Подпись удалена модератором>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.