intel ++:警告#1563:取一个临时的地址 - 误报?

时间:2013-05-23 13:38:10

标签: c++ icc

我上了这堂课:

class myClass
{
private:
      struct tm minDate, maxDate;
public:
      myClass();

      struct tm GetMinDate()  {return minDate;};
      struct tm GetMaxDate()  {return maxDate;};
};

和这个函数调用

SetMinMaxDate(struct tm *MinDate, struct tm *MaxDate);

以下代码

myClass myInstance;
SetMinMaxDate(&myInstance.GetMinDate(), &myInstance.GetMaxDate());

运行良好,MSVC 2010和2005没有生成任何警告。但是,如果我用intel C ++编译它,我会得到警告

warning #1563: taking the address of a temporary

根据this related thread

  

临时对象(也称为右值)的生命周期是绑定的   表达式和临时对象的析构函数是   在完整表达结束时调用

SetMinMaxDate复制用指针传递的内容。指针本身不存储。 因此,在SetMinMaxDate返回之前,2个临时tm元素应该有效。

此代码中是否存在问题,或者这是英特尔C ++的误报?

修改 我找到了另一篇非常有趣的帖子,说明了这种行为的原因: Why is it illegal to take the address of an rvalue temporary?

4 个答案:

答案 0 :(得分:6)

这是一个有效的警告,因为SetMinMaxDate()不保证它不会存储该指针供以后使用。并且由于您正在向临时传递指针,如果SetMinMaxDate存储它以供以后使用,那将是一个问题。

警告的另一个原因是,使用声明,可能SetMinMaxDate 修改通过指针传入的tm结构,这样的修改会丢失,因为它是指向临时对象。

SetMinMaxDate最好声明为:

SetMinMaxDate(const struct tm & MinDate, const struct tm & MaxDate);
在这种情况下,没有警告。 const允许编译器知道它不会修改对象,而&表示它不太可能试图存储该地址以供日后使用。

答案 1 :(得分:5)

根据C ++ 11标准的第5.3.1 / 3段:

  

一元&运算符的结果是指向其操作数的指针。 操作数应为左值或限定ID 。 [...]

不仅警告是合适的,我更想知道为什么它不是错误。你的节目是不正确的,因为临时不是左撇子。可能,MSVC支持这作为编译器扩展 - 但这个扩展的价值是相当有争议的。

答案 2 :(得分:0)

myClass myInstance;
{
struct tm a,b;
a = myInstance.GetMinDate();
b = myInstance.GetMaxDate();
SetMinMaxDate(&a, &b);
}

应如何实施它。

根据我的灰色记忆,你可能无法获得rvalue的地址 - 这就是你所做的。

如此简短:英特尔C是对的

答案 3 :(得分:0)

问:这个代码中是否存在问题,或者这是英特尔C ++的误报? 答:我在这段代码中看到了这个问题。

函数GetMinDate()返回一个理论上可以存储在处理器寄存器中的值。因此它没有地址。大多数编译器会将返回值存储在一个临时的生命周期中。到目前为止,没问题。

 struct tm GetMinDate()  {return minDate;};

稍后您在

中引用此结果的“地址”
... &myInstance.GetMinDate() ...

现在你有问题了。另一个操作可以快速使用临时地址,例如myInstance.Get * Max * Date()的结果。

@drahnr建议实施是一个很好的解决方案。

另一个但是结构tm较差的方法是将参数传递给SetMinMaxDate()作为值

SetMinMaxDate(struct tm MinDate, struct tm MaxDate);