Russian Qt Forum

Qt => Установка, сборка, отладка, тестирование => Тема начата: andrew.k от Июнь 12, 2014, 15:53



Название: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 15:53
Во вложении, очень маленький тестовый проект проект.
Его компиляция в Kubuntu 14.04 х86_64 (а так же в еще одном другом линуксе) и последующий запуск приводит к краху приложения (SIGSEGV), причем где-то в недрах Qt.

Под виндой не пробовал. Если кто сможет, отпишитесь.
Если у кого-то этот проект работает, тоже отпишитесь.

Собственно вопрос задачи, что не так с проектом?
Там один интерфейс, одна реализация и использование этого добра.
Все предельно очевидно. Но не работает.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: gil9red от Июнь 12, 2014, 16:01
Qt 4.8.*, mingw 4.6.2, Windows XP
Цитировать
Запускается C:\test_bad\build-arms-Desktop-Debug\debug\arms.exe...
"BaseApplication" "registered"
C:\test_bad\build-arms-Desktop-Debug\debug\arms.exe завершился с кодом 1


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: Old от Июнь 12, 2014, 16:16
Ну так порядок инициализации статических объектов не определен. :)

Перенесите это:
Код
C++ (Qt)
IApplication::IAppMap IApplication::_impl;

перед этим:
Код
C++ (Qt)
BaseApplication BaseApplication::_application;


А вообще, лучше так не мудрить.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:21
Ну так порядок инициализации статических объектов не определен. :)

Перенесите это:
Код
C++ (Qt)
IApplication::IAppMap IApplication::_impl;

перед этим:
Код
C++ (Qt)
BaseApplication BaseApplication::_application;
[.quote]
А как же его перенести, если они в разных файлах находятся? При этом по идее IApplication::IAppMap IApplication::_impl; должен быть по коду и так выше, ведь он инклудится в BaseApplication

А вообще, лучше так не мудрить.
Что плохого в этом коде?


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:24
Ну так порядок инициализации статических объектов не определен. :)
Вот у gil9red mingw почему-то смог определить порядок инициализации, приложение работает.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: Old от Июнь 12, 2014, 16:26
А как же его перенести, если они в разных файлах находятся? При этом по идее IApplication::IAppMap IApplication::_impl; должен быть по коду и так выше, ведь он инклудится в BaseApplication
Просто перенесите ее в другой файл и тогда map сконструируется раньше.

Что плохого в этом коде?
Вот как раз это.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:30
А как же его перенести, если они в разных файлах находятся? При этом по идее IApplication::IAppMap IApplication::_impl; должен быть по коду и так выше, ведь он инклудится в BaseApplication
Просто перенесите ее в другой файл и тогда map сконструируется раньше.
В какой другой? как это повлияет на порядок инициализации? Никак.
При этом нарушится модульность. Почему часть кода IApplication должна быть в другом файле?


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: Old от Июнь 12, 2014, 16:34
В какой другой? как это повлияет на порядок инициализации? Никак.

Сделайте так и у вас все заработает:
Код
C++ (Qt)
#include "baseapplication.h"
 
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
 
using namespace core;
 
IApplication::IAppMap IApplication::_impl;
BaseApplication BaseApplication::_application;
QCoreApplication * BaseApplication::qtapp = 0;
 
BaseApplication::BaseApplication()
   :IApplication()
{
   registerImplementation("BaseApplication", this);
}
 
int BaseApplication::run()
{
   if(qtapp)
       return 0;
   else
       return 1;
}
 
void BaseApplication::onInitialized()
{
   qDebug() << QObject::tr("BaseApplication initialized");
}
 

При этом нарушится модульность. Почему часть кода IApplication должна быть в другом файле?
Вот поэтому так, как сделали вы, делать не надо.
И тогда не понадобиться использовать такие костыли.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:38
В какой другой? как это повлияет на порядок инициализации? Никак.

Сделайте так и у вас все заработает:
А что делать, когда появится еще один наследник?
class AdvancedApplication : public IApplication например.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:43
В общем, "Диктую ответ на 1 -й вопрос 9-го билета."  ;D

Действительно проблема в порядке инициализации статических объектов.

Варианты решений:
  • В файле проекта в секции SOURCES нужно перенести iapplication.cpp над baseapplication.cpp
    Это влияет на порядок инициализации и приложение будет работать.
  • Задать высокий приоритет для статического объекта _impl класса IApplication
    Таким образом IApplication::IAppMap IApplication::_impl __attribute__ ((init_priority(101)));
    Но это решение не кроссплатформенное кажется.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: Old от Июнь 12, 2014, 16:47
А что делать, когда появится еще один наследник?
Надеятся, что все будет хорошо (что он будет инициализироваться после конструирования map).
Так как в стандарте порядок инициализации статических объектов не определен, то получается лотерея. Один компилятор может инициализировать в одном порядке, другой в другом. Поменяете порядок линкуемых файлов - все может измениться. И т.д.
Поэтому, так лучше не делать. Или выносить такую инициализацию в отдельный файл и там прописывать в нужной последовательности.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 16:49
А что делать, когда появится еще один наследник?
Надеятся, что все будет хорошо (что он будет инициализироваться после конструирования map).
Так как в стандарте порядок инициализации статических объектов не определен, то получается лотерея. Один компилятор может инициализировать в одном порядке, другой в другом. Поменяете порядок линкуемых файлов - все может измениться. И т.д.
Поэтому, так лучше не делать. Или выносить такую инициализацию в отдельный файл и там прописывать в нужной последовательности.
А почему компилятор сам не может увидеть зависимость одного объекта от другого?
С отдельным файлом, некрасиво как-то :/

А как бы сделать аналогичную структуру без статических объектов?


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: Old от Июнь 12, 2014, 17:06
А почему компилятор сам не может увидеть зависимость одного объекта от другого?
Компилятор компилирует единицу трансляции (один файл), про другие он даже не догадывается.

А как бы сделать аналогичную структуру без статических объектов?
Все компиляторы которые я видел, инициализировали в порядке линковки объектных файлов.
Если вы будете соблюдать порядок в котором, iapplication будет идти перед остальными наследниками, то все должно работать.

А так, почитайте Александреску про синглетоны, он подобные случаи неплохо разбирает.


Название: Re: Задача для специалистов (в чем ошибка)
Отправлено: andrew.k от Июнь 12, 2014, 18:38
А почему компилятор сам не может увидеть зависимость одного объекта от другого?
Компилятор компилирует единицу трансляции (один файл), про другие он даже не догадывается.

А как бы сделать аналогичную структуру без статических объектов?
Все компиляторы которые я видел, инициализировали в порядке линковки объектных файлов.
Если вы будете соблюдать порядок в котором, iapplication будет идти перед остальными наследниками, то все должно работать.

А так, почитайте Александреску про синглетоны, он подобные случаи неплохо разбирает.

Спасибо за полезные ответы.