Законно ли использовать функции, возвращающие временное значение, в списках инициализаторов?

У меня есть следующий конструктор объекта

Segment::Segment(QPointF const& start, QPointF const& end):
  mOrigin(toVector3df(start)),mEnd(toVector3df(end)){    
}

mOrigin имеет тип Vector3df, а функция toVector3df(QPointF const&) возвращает временный Vector3df. Все идет нормально. Код прекрасно компилируется и отлично работает под Linux, gcc 4.4.3. активировано большинство предупреждений.

Теперь я хотел кросс-компилировать тот же код для смартфона Nokia (Meamo Fremantle), и вдруг я получаю очень странные предупреждения компилятора:

include/vector3d.h: In constructor 'Segment::Segment(const QPointF&, const QPointF&)':
include/vector3d.h:64: warning: 'this.902' is used uninitialized in this function
include/vector3d.h:64: note: 'this.902' was declared here

Во-первых: Конечно, внутри Vecto3df нет настоящей переменной с именем this.902, поэтому мой первый вопрос будет таким: «Кто-нибудь видел подобное предупреждение?» Кроме того, нет ничего плохого в конструкторах Vector3df, они очень просты, а toVector3df(QPointF const&) — это однострочная функция шаблона, не являющаяся членом, которая отлично работает в других частях кода. Vector3df наследуется от шаблона, который определяет только функции, не являющиеся членами, никаких переменных нет, виртуальные функции.

Во-вторых, когда я изменяю приведенный выше код на следующий

Segment::Segment(QPointF const& start, QPointF const& end):
  mOrigin(),mEnd(){
  mOrigin = toVector3df(start);
  mEnd = toVector3df(end);
}

Код работает нормально, без каких-либо предупреждений. Итак, что мне здесь не хватает? Кто-нибудь знает, что может быть источником предупреждений. Я нарушаю какое-то учение, о котором не знаю. Является ли компилятор fremantle (Maemo 5, Qt 4.6.2) более серьезным или глючным?

Заранее спасибо, Мартин

Изменить: вот минимальный пример, извините за длину: -P

#include <iostream>
#include <sstream>
#include <QPoint>

template<typename T> class IoEnabled {};

template<typename T>
class Vector3d: public IoEnabled<Vector3d<T> > {
  private:
    T mX; T mY; T mZ;
  public:
    Vector3d(T const& x, T const& y, T const& z=0.0) : mX(x), mY(y), mZ(z) {}
};
typedef Vector3d<float> Vector3df;

template<class T>
Vector3df toVector3df(T const& p){
  return Vector3df(p.x(),p.y(),0.0);
}

class Segment {
  private:
    Vector3df mOrigin; Vector3df mEnd;
  public:
    Segment(QPointF const& start, QPointF const& end):
        mOrigin(toVector3df(start)),mEnd(toVector3df(end)){
        //if toVector3df(...) is moved from the initializer to the body it works
    }
};

int main(int argc, char **argv) {
  (void) argc; (void) argv;
  Segment temp(QPointF(1,2),QPointF(3,4));
  return 0;
}

Вызов компилятора:

 g++ -c -pipe -Werror -Wall -Wextra -Wunused -Wundef -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -D_REENTRANT -Wall -W -DQT_GL_NO_SCISSOR_TEST -DQT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH=1024 -DMAEMO -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/QtSDK/Maemo/4.6.2/sysroots/fremantle-arm-sysroot-20.2010.36-2-slim/usr/share/qt4/mkspecs/linux-g++-maemo5 -I. -I/opt/QtSDK/Maemo/4.6.2/sysroots/fremantle-arm-sysroot-20.2010.36-2-slim/usr/include/QtCore -I/opt/QtSDK/Maemo/4.6.2/sysroots/fremantle-arm-sysroot-20.2010.36-2-slim/usr/include/QtGui -I/opt/QtSDK/Maemo/4.6.2/sysroots/fremantle-arm-sysroot-20.2010.36-2-slim/usr/include -Isrc -Irelease/moc -o release/obj/main.o src/main.cpp

Наследование шаблона, кажется, имеет решающее значение, если Vector3d не наследует, все работает нормально.


person Martin    schedule 17.01.2012    source источник
comment
Является ли toVector3df функцией-членом?   -  person Seth Carnegie    schedule 17.01.2012
comment
Нет шаблона, не являющегося членом   -  person Martin    schedule 17.01.2012
comment
Можете ли вы воспроизвести это в небольшом примере, который можно вставить в вопрос?   -  person Mark B    schedule 17.01.2012
comment
@Mark: Готово, параметры Comiler кажутся важными. Без -O3 и некоторых других он скомпилирован   -  person Martin    schedule 17.01.2012


Ответы (1)


Нет ничего плохого в использовании функций, возвращающих временные списки инициализаторов членов.
Даже порядок, в котором члены будут инициализированы, четко определен в стандарте.

person Alok Save    schedule 17.01.2012
comment
Хорошо, это было и мое впечатление, с облегчением увидев, что оно подтвердилось. Есть идеи, на что жалуется компилятор? - person Martin; 17.01.2012
comment
@Martin: Можете ли вы создать небольшой минималистичный автономный код и скомпилировать его на рассматриваемом компиляторе, чтобы воспроизвести ошибку? - person Alok Save; 17.01.2012
comment
Наконец да, смотрите мое редактирование. Если хотите попробовать, обратите внимание на параметры компилятора. Чуть другой (без O3) не приводил к ошибке - person Martin; 17.01.2012