Is it legal to use functions returning a temporary in initialiser lists

126 views Asked by At

I have the following constructor of an object

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

mOrigin is of type Vector3df and the function toVector3df(QPointF const&) returns a temporary Vector3df. So far so good. The code compiles fine and works like a charm under linux, gcc 4.4.3. most warnings activated.

Now I wanted to cross-compile the same code for a Nokia Smartphone (Meamo Fremantle) and all of a sudden I get very weird compiler warnings:

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

First: Of course there is no real variable called this.902 inside 'Vecto3df' so my first question would be: "Has anyone seen some warning like this ?" Further there is nothing wrong with Vector3df constructors, they are very simple and toVector3df(QPointF const&) is a one liner non-member template function that works perfect in other parts of the code. Vector3df inherits from a template that only defines non-member functions, no variables no, virtual functions.

Second, when I change the above code to the following

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

The code works fine without any warnings. So what am I missing here ? Has anybody an idea what the origin of the warnings could be. Am I violating some doctrine I'm unaware of. Is the fremantle compiler (Maemo 5, Qt 4.6.2) more severe or buggy ?

Thanks in advance, Martin

Edit: Here is a minimal example, sorry for the length :-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;
}

Compiler call:

 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

The Template inheritance seems to be crucial, if the Vector3d does not inherit everything works fine.

1

There are 1 answers

3
Alok Save On BEST ANSWER

There is nothing wrong in using functions returning a temporary in member initializer lists.
Even the order in which the members will be inialized is well defined in the standard.