Russian Qt Forum
Ноябрь 25, 2024, 02:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Зверский баг  (Прочитано 7145 раз)
Dodge
Гость
« : Апрель 16, 2008, 13:09 »

Недавно словил зверский баг у себя в проекте - при вызове слота в результате эмита сигнала с параметрами, в слоте аргумента в буквальном смысле нету. Приведу пример для наглядности:

Код:
void MyQObjectBasedClass::valueChanged( QDateTime dt ) {
    qDebug() << "value:" << &dt;
}
Вывод:
Код:
value: 0x0

Эмитит сигнал Qt-виджет(QDateTimeEdit).

Коннект:
Код:
QDateTimeEdit * edit = new QDateTimeEdit;
...
MyQObjectBasedClass * myobject = new MyQObjectBasedClass;
...
connect( edit, SIGNAL( dateTimeChanged(QDateTime) ),
    myobject, SLOT( valueChanged(QDateTime) ) );

К эмиту приводит:
Код:
edit->setDateTime( .../*тут например QDateTime::currentDateTime(), хотя писал и константы*/ );

Такая ситуация со всеми (покрайней мере "моими") слотами.
Баг именно у меня в проекте, т.к. потестив виджет отдельно, такогоже эффекта не получил. Есть какие нибудь мысли по этому поводу?
Записан
ритт
Гость
« Ответ #1 : Апрель 16, 2008, 13:25 »

ага...есть одна:
замени
Код:
connect( edit, SIGNAL( dateTimeChanged(QDateTime) ),
    myobject, SLOT( valueChanged(QDateTime) ) );
на
Код:
connect( edit, SIGNAL( dateTimeChanged ( const QDateTime &) ), myobject, SLOT( valueChanged ( const QDateTime &) ) );
ну, и слот подправь должным образом...
Записан
Dodge
Гость
« Ответ #2 : Апрель 16, 2008, 19:23 »

что за бред... вы прежде чем писать проверьте... ссылка не есть тип...

З.Ы.
как я понимаю вы же в кандидаты перенесли, хочется обратно...
« Последнее редактирование: Апрель 16, 2008, 19:25 от Dodge » Записан
Dodge
Гость
« Ответ #3 : Апрель 16, 2008, 19:35 »

ах да, Qt 4.3.2
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Апрель 16, 2008, 19:58 »

что за бред... вы прежде чем писать проверьте... ссылка не есть тип...

 Непонимающий

Попрошу здесь поподробнее

Upd:

Проверил, все работает нормально, Qt 4.3.4

Код:
connect(dateTimeEdit, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(valueChanged1(QDateTime)));
connect(dateTimeEdit, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT( valueChanged2(const QDateTime &)));

.....

void Test::valueChanged1(QDateTime dt)
{
    qDebug() << "valueChanged1:" << &dt;
}

void Test::valueChanged2( const QDateTime &dt )
{
    qDebug() << "valueChanged2:" << &dt;
}

Как вариант, делаем апдейт до 4.3.4
« Последнее редактирование: Апрель 16, 2008, 20:09 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Dodge
Гость
« Ответ #5 : Апрель 16, 2008, 21:08 »

Цитировать
Проверил, все работает нормально, Qt 4.3.4
Очень интересно, дело в том, что я пробовал вариант со ссылкой, но коннект не проходил...

...хотя с др стороны, в простой то программе у меня тоже все работает как надо! Мне дико интересно, что может привести к такому эффекту... Мистика! в мок-файле(файл сгенерированный моком Улыбающийся) идет явный вызов метода, в этом случае даже если объект ссылка на который передается - "умер", мы должны получить в слоте адресс того места(не то о чем вы подумали, имеется ввиду память) где был объект.
Записан
Вячеслав
Гость
« Ответ #6 : Апрель 16, 2008, 21:25 »

...хотя с др стороны, в простой то программе у меня тоже все работает как надо! Мне дико интересно, что может привести к такому эффекту... Мистика!

Ну может быть "провалы"(ляпы ) в памяти Подмигивающий Самое тупое -  объект не в куче,а в стеке Подмигивающий Цитируя gmane.comp.db.firebird.russian - "ЫЩИ ХЛУБЖЕ" Подмигивающий А серьезно - пробегись шагами по проге с момента emit'а глядя на стек - может чего углядишь ( на скорую руку).
Записан
Alex03
Гость
« Ответ #7 : Апрель 17, 2008, 08:29 »

Насколько я понимаю то что
Код:
void MyQObjectBasedClass::valueChanged( QDateTime dt ) {
    qDebug() << "value:" << &dt;
}
Выдаёт:
Код:
value: 0x0
никак не зависит от того слот это (законнекченный), или просто метод, в любом случае dt приходит в функцию в соответствии с соглашением о вызовах.
Т.е. на стеке или в регистрах проца - зависит от архитектуры проца, компилятора, его опций оптимизации, от самого передаваемого объекта (его размера) и т.д.
В данном случае dt содержит единственный указатель на QDateTimePrivate, поэтому легко может уместиться в регистр проца...
В общем проблема не в Qt а к компиляторе.
Поэтому Dodge, огласи платформу, ОС, компилятор и его версию и опции...

Точно не уверен (надо смотреть стантарт), но в таком случае если в коде есть взятие адреса от переменно которая может быть переданна в регистре проца компилятор должен нагенерить код по переносу этой переменной в стек и давать адрес именно этой новой переменной.

Вот это:
Код:
void MyQObjectBasedClass::valueChanged( QDateTime dt ) {
    qDebug() << "value:" << dt;
}
нормально работает?
Записан
Dodge
Гость
« Ответ #8 : Апрель 17, 2008, 13:45 »

Поэтому Dodge, огласи платформу, ОС, компилятор и его версию и опции...
Linux gentoo 32bit, g++(4.2.2), использую систему сборки cmake(2.4-path 7), поэтому напрямую компилятору ничего не задаю  Улыбающийся


Вот это:
Код:
void MyQObjectBasedClass::valueChanged( QDateTime dt ) {
    qDebug() << "value:" << dt;
}
нормально работает?
ну я чесно говоря такого вопроса не ожидал Улыбающийся... ошибку сигментации выдает, объекта то нету  Шокированный
Записан
Tonal
Гость
« Ответ #9 : Апрель 17, 2008, 14:04 »

Сигнал не между потоками кидается?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #10 : Апрель 17, 2008, 14:28 »

Хм, интересная ситуация получаеться...

У меня такой вот вопросик: а обыекты, приведенные ниже, нигде не удаляються на момент испускания (или на помент обработки) сигнала:

Код:
QDateTimeEdit * edit = new QDateTimeEdit;
MyQObjectBasedClass * myobject = new MyQObjectBasedClass;
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Dodge
Гость
« Ответ #11 : Апрель 17, 2008, 16:12 »

Сигнал не между потоками кидается?
нет, все происходит в основном потоке.

Цитировать
Хм, интересная ситуация получаеться...

У меня такой вот вопросик: а обыекты, приведенные ниже, нигде не удаляються на момент испускания (или на помент обработки) сигнала:

Code:
QDateTimeEdit * edit = new QDateTimeEdit;
MyQObjectBasedClass * myobject = new MyQObjectBasedClass;
покрайней мере мной нет.
проверку на валидность сендера ставил + вызывал метод сендера и получал от него правильный результат:
Код:
if( QDateTimeEdit * editor = qobject_cast<QDateTimeEdit*>(sender()) )
    qDebug() << "sender value:" << editor->dateTime();

приемник не проверял, операясь на то, что если бы приемника небыло, то в следствии попытки вызвать его слот, программа бы вылетала с ошибкой сигментации.
Записан
Tonal
Гость
« Ответ #12 : Апрель 17, 2008, 16:29 »

Получить такое же поведение можно примерно так:
Код:
void f(int i) {
  cout<<&i<<endl;
}
void ff(const int& i) {
  f(i);
}
void fff(const int* i) {
 ff(*i);
}
int main() {
  fff(0);
}
Если f заинлайнится...
Хотя на этом тесте екзешник деланный мингвой высыпается на f(i).

P.S. Похоже ты наткнулся на какой то баг gcc + Qt. Я на подобные в багланде часто натыкался.
Попробуй сделать минимальный пример и послать тролям.
« Последнее редактирование: Апрель 17, 2008, 16:33 от Tonal » Записан
Tonal
Гость
« Ответ #13 : Апрель 17, 2008, 16:43 »

Вот ещё один примерчег:
Код:
struct test_t {
  int i[12];
};
void f(test_t i) {
  cout<<i.i<<" "<<&i<<endl;
}
void ff(const test_t& i) {
  cout<<&i<<endl;
}
typedef void (*FF)(const test_t&);
void fff(const test_t* i, FF f) {
  f(*i);
}
int main() {
  fff(0, (FF)f);
  fff(0, (FF)ff);
}
Это уже больше походит на то, что происходит при вызове слота...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.122 секунд. Запросов: 22.