1. C++ / Говнокод #19390

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    // Определение метода  Q3CanvasText::text() 
    
    class Q_COMPAT_EXPORT Q3CanvasText : public Q3CanvasItem {
    //...
      QString text() const;
    //...
    };
    
    // Далее уже в "моем" классе строчка:
    class CDevice : public CDiagramObject {
    // ...
    private:
      Q3CanvasText * m_pTitle;
    //....
    public:
      const QString & stitle() const { return m_pTitle->text(); } // обратим вниманиена возвращаемый тип
    // ...
    };
    
    // Еще один класс и отображение тултипа при наведении
    void CDiagramView::showToolTip( const QPoint & p, CDevice * d ) {
    
        if( d ) {
            QString tmp;
            if( d->group() == QString::null || d->group() == "" )
                tmp = ( d->stitle().left( d->stitle().indexOf(":") ) );  // вылетало здесь : d->stitle().indexOf(":") segmentation fault
            else
                tmp = d->group();
    //.....
            }
        }

    Нашел магию!

    Юзаю Qt 4.8.6 в Linux
    Под Виндой новая версия перепиливаемой проги компилится и работает,
    под Линухом новая версия вылетает, старая робит.

    Соль в том, что метод stitle() по факту возвращает ссылку на копию текста возвращенного Q3CanvasText::text(), которая внезапно удаляется при выходе из метода.

    Но почему тот же gcc под виндой скомпилил это без багов?

    Запостил: OlegUP, 03 Февраля 2016

    Комментарии (11) RSS

    • P.S. ЧСХ я не трогал эти классы
      Ответить
    • > без багов
      UB же. Самая подлость в том, что UB'ы иногда работают. Другое соглашение о вызовах было, другая глубина стека, другие оптимизации... Вот и повезло, что не затёрлись данные, когда под виндой запустил.

      > const QString &
      Дооптимизировались, блять. Походу, раньше поле было просто QString'ом. И ссылку возвращали ради оптимизации, чтобы не копировалось. А потом тип у поля поменяли, а у функции - забыли.
      Ответить
      • P.P.S. Ссылки в возвращаемых значениях - преждевременная оптимизация и моветон. Кроме, пожалуй, операторов <<, >> и [].
        Ответить
        • Еще можно соорудить что-то типа obj.method1().method2().method3().finali ze()

          Но в этом случае, правда, и ситуация немного другая выходит: this (неявный аргумент) должен жить и после вызова метода
          Ответить
      • Внутри QString copy on write. И так не копируется.
        Ответить
        • Атомарный инкремент счётчика ссылок, между прочим, не такая уж и дешёвая операция!
          Ответить
          • да там во всём Qt тонны дешевых операций. Оптимизировал везде по чуть-чуть и едет быстрее.
            Ответить
    • P.S. Не пора ли это говно мамонта закопать или переписать под что-то более свежее, чем Qt 4.8 в режиме совместимости с 3.х? :)
      Ответить
      • Времени по документам нету на это, да и зачем? Программа будет раз в полгода юзаться если повезет.
        Ответить
    • на дворе 2016 год, а автор пользует Qt4 с легаси классами аж от самой Qt3.
      "This class is part of the Qt 3 support library. It is provided to keep old source code working. We strongly advise against using it in new code. See Porting to Qt 4 for more information."
      Ответить
      • вы читали топик?
        > Под Виндой новая версия перепиливаемой проги
        Ответить

    Добавить комментарий