crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Непонятная проблема при компиляции релиза
MishaUA
  опции профиля:
сообщение 21.8.2013, 10:39
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 185
Регистрация: 28.4.2013
Пользователь №: 3810

Спасибо сказали: 13 раз(а)




Репутация:   0  


есть такой код:
/////////// status.h
class s_StatusSettings {
public:
    s_StatusSettings();
    friend QDataStream &operator<<(QDataStream &, const s_StatusSettings &);
    friend QDataStream &operator>>(QDataStream &, s_StatusSettings &);

    QString lab,
            img;

};
Q_DECLARE_METATYPE(s_StatusSettings)

/////////// status.c
inline QDataStream &operator<<(QDataStream &stream, const s_StatusSettings &obj) {
    stream << obj.lab << obj.img;
    return stream;
}
inline QDataStream &operator>>(QDataStream &stream, s_StatusSettings &obj) {
    stream >> obj.lab >> obj.img;
    return stream;
}

s_StatusSettings::s_StatusSettings() {
    qRegisterMetaTypeStreamOperators<s_StatusSettings>("s_StatusSettings");
}


/////////// main.cpp  к которому подключен status.h
s_StatusSettings*    dSettings = new s_StatusSettings();

QFile file("file");    
if(file.open(QIODevice::ReadOnly))    // открываем файл
{
    // читаем с файла
    QDataStream stream(&file);
    stream >> *dSettings;

    if(stream.status() != QDataStream::Ok) qDebug() << "Ошибка чтения файла";
    file.close();
}

Здесь вроде все понятно. Если компилирую debug версию, то собирается без ошибок и отлично работает, а если release, то при сборке показывает такие ошибки:
main.cpp:-1: ошибка: undefined reference to `operator>>(QDataStream&, s_StatusSettings&)'
:-1: ошибка: ./release\main.o: bad reloc address 0x3f0 in section `.gcc_except_table'

Пробовал делать полную очистку, не не помогло.
Где я ошибся?
Спасибо!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilyabvt
  опции профиля:
сообщение 21.8.2013, 17:53
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 297
Регистрация: 23.6.2011
Пользователь №: 2765

Спасибо сказали: 45 раз(а)




Репутация:   3  


Линкер не видит определения операторов. Попробуйте включить определения в объявление класса, вы все равно методы inline делаете.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MishaUA
  опции профиля:
сообщение 22.8.2013, 0:46
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 185
Регистрация: 28.4.2013
Пользователь №: 3810

Спасибо сказали: 13 раз(а)




Репутация:   0  


так работает)))))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MishaUA
  опции профиля:
сообщение 22.8.2013, 10:32
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 185
Регистрация: 28.4.2013
Пользователь №: 3810

Спасибо сказали: 13 раз(а)




Репутация:   0  


а можно ли сделать так, чтобы линкер видел определения в *.сpp файле? Просто там хидер слишком большой получается
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilyabvt
  опции профиля:
сообщение 22.8.2013, 16:53
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 297
Регистрация: 23.6.2011
Пользователь №: 2765

Спасибо сказали: 45 раз(а)




Репутация:   3  


Всего 6 строк добавляется. Уберите ключевое слово inline. Встраиваемые методы должны определятся в том же модуле что и класс.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.8.2013, 20:06
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


засовывание всего в заголовочники - это неправильный подход. в норме, в проект должен быть добавлен файл cpp. как это делается в Qt, я не знаю, но надо просто добавить файл status.c.
не очень понятно, почему файл имеет расширение .с, когда он явно CPP-шный. возможно, в настройках что-то не так. компияторы различают .c и .cpp и для компиляции файла .c как CPP надо дополнительно указывать настройки компилятору.

Сообщение отредактировал Iron Bug - 22.8.2013, 20:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilyabvt
  опции профиля:
сообщение 22.8.2013, 20:14
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 297
Регистрация: 23.6.2011
Пользователь №: 2765

Спасибо сказали: 45 раз(а)




Репутация:   3  


Цитата
засовывание всего в заголовочники - это неправильный подход. в норме, в проект должен быть добавлен файл cpp. как это делается в Qt

Полностью согласен. Но встраиваемые функции засовывают в заголовочники, в том числе и в Qt.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MishaUA
  опции профиля:
сообщение 22.8.2013, 20:53
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 185
Регистрация: 28.4.2013
Пользователь №: 3810

Спасибо сказали: 13 раз(а)




Репутация:   0  


заработало после того, как убрал inline))))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 23.8.2013, 12:49
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


на самом деле, в данном случае inline всё равно работать не будет, потому что есть возвращаемое значение и return. подробно ограничения на inline описаны, например, здесь. ограничений довольно много.
но если уж очень хочется оптимизировать вызовы, то можно использовать т.н. оптимизацию при линковке (link-time optimization). в более-менее свежих компиляторах она поддерживается. например, в msvc это опция /LTCG, в gcc это опция -flto. собственно, это "inline" на уровне линковщика. подробнее можно почитать тут.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 12:16