在初始化列表中使用返回临时对象的函数是否合法?

4
我有一个对象的以下构造函数
Segment::Segment(QPointF const& start, QPointF const& end):
  mOrigin(toVector3df(start)),mEnd(toVector3df(end)){    
}

mOriginVector3df类型,函数toVector3df(QPointF const&)返回一个临时的Vector3df。代码能够正常编译并在Linux、gcc 4.4.3环境下运行良好。

现在我想将相同的代码交叉编译到诺基亚智能手机(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);
}

代码运行正常,没有任何警告。 那么我在这里缺少什么?有人知道警告的起源是什么吗?我是否违反了一些我不知道的教义?芬曼特尔编译器(Maemo 5,Qt 4.6.2)更严格还是更有bug? 提前感谢,Martin
编辑: 这里是一个最小化示例,抱歉长度 :-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不继承,则模板继承似乎非常重要,否则一切正常。


toVector3df 是一个成员函数吗? - Seth Carnegie
非成员模板。 - Martin
你能否在问题中粘贴一个小的示例来重现这个问题? - Mark B
@Mark:已完成,编译器选项似乎很重要。没有-O3和其他一些选项它就能编译。 - Martin
1个回答

3
在成员初始化列表中使用返回临时对象的函数并没有问题。
即使成员初始化的顺序在标准中也有明确定义。

好的,这也是我的印象,很高兴看到它得到了确认。你有什么想法,编译器在抱怨什么? - Martin
@Martin:你能否创建一个小型的极简独立代码,并在问题中的编译器上进行编译,以重现错误? - Alok Save
最后,是的,请看我的编辑。如果你想尝试它,请注意编译器参数。稍微不同的一个(没有O3)没有导致错误。 - Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接