[eigen] is returning Eigen::Ref objects legit? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: [eigen] is returning Eigen::Ref objects legit?
- From: Sébastien Barthélémy <barthelemy@xxxxxxxxx>
- Date: Mon, 20 May 2013 15:38:12 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:sender:date:x-google-sender-auth:message-id :subject:from:to:content-type; bh=Cspqy9+Xl2tXgs3ygsCCV0xQaGH2Ug3ub3dilro8k1M=; b=YspsijntOOgSb56wTd0j3a7d2xoCpMdubL+CZGMyKZnlmXBn7nmh/6wZziPPinHdUy i4glVOx6E3R4LRCOsT9xecWtJho76G0OVExXWiYyGYF5bwVlnkWDY66CsLiqjJFQexaI oCsNUL1jY7kCM6U5NL3YCZ3c80eDZwma2BeKTPi2l+TLHHCnkAkDWWEk/pun54uazQJm cAE7u+SQuLJk/NbiLJRrhFT7IcfxqYpk63zBNWW0DJg67FMuBDF/NdT26nxwYl3mWbdD qPxNf0jbadIbCdnou4Xqh3aoyf2vuzMTYrnPM0RPZZyzXSHaHPLTFSAoR8CRW/UvOlEp PXXw==
Hello,
I'm giving new Eigen::Refs a try and thought they might be a handy
type to return (by const ref), especially when the implementation
knows the matrix size at compile time but the caller does not.
However, I'm not sure they are intended to be returned. The doc says
"This class permits to write non template functions taking Eigen's
object as parameters".
Moreover my small test gets a "returning reference to temporary"
warning at compile time and a std::bad_alloc exception at runtime.
This does not sound good ;).
Could you please confirm in either way?
Example and backtrace are attached just in case.
Thanks!
(gdb) bt
#0 0x00007ffff723f425 in __GI_raise (sig=<optimized out>) at
.../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff7242b8b in __GI_abort () at abort.c:91
#2 0x00007ffff7b9169d in __gnu_cxx::__verbose_terminate_handler() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7b8f846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7b8f873 in std::terminate() () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7b8f96e in __cxa_throw () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x0000000000411862 in Eigen::internal::throw_std_bad_alloc () at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/util/Memory.h:81
#7 0x000000000041189c in Eigen::internal::aligned_malloc
(size=3377699720330112) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/util/Memory.h:225
#8 0x0000000000411d56 in
Eigen::internal::conditional_aligned_malloc<true>
(size=3377699720330112) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/util/Memory.h:294
#9 0x0000000000413f15 in
Eigen::internal::conditional_aligned_new_auto<float, true>
(size=844424930082528) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/util/Memory.h:414
#10 0x0000000000413b7e in Eigen::DenseStorage<float,
-0x00000000000000001, 6, -0x00000000000000001, 0>::DenseStorage
(this=0x7fffffffe0d0, size=844424930082528, nbCols=140737488347088)
at /home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/DenseStorage.h:265
#11 0x00000000004134ce in Eigen::PlainObjectBase<Eigen::Matrix<float,
6, -0x00000000000000001, 0, 6, -0x00000000000000001>
>::PlainObjectBase (this=0x7fffffffe0d0, a_size=844424930082528,
nbRows=6, nbCols=140737488347088)
at /home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/PlainObjectBase.h:438
#12 0x0000000000412937 in Eigen::Matrix<float, 6,
-0x00000000000000001, 0, 6, -0x00000000000000001>::Matrix
(this=0x7fffffffe0d0, other=...) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/Matrix.h:285
#13 0x0000000000412074 in Eigen::Ref<Eigen::Matrix<float, 6,
-0x00000000000000001, 0, 6, -0x00000000000000001> const, 0,
Eigen::OuterStride<-0x00000000000000001> >::Ref (this=0x7fffffffe0a8)
at /home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/Ref.h:216
#14 0x0000000000413af2 in
Eigen::internal::BlockImpl_dense<Eigen::Ref<Eigen::Matrix<float, 6,
-0x00000000000000001, 0, 6, -0x00000000000000001> const, 0,
Eigen::OuterStride<-0x00000000000000001> > const,
-0x00000000000000001, -0x00000000000000001, false,
true>::BlockImpl_dense (this=0x7fffffffe090, xpr=..., startRow=0,
startCol=0, blockRows=3, blockCols=140737488347168) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/Block.h:350
#15 0x00000000004133d4 in
Eigen::BlockImpl<Eigen::Ref<Eigen::Matrix<float, 6,
-0x00000000000000001, 0, 6, -0x00000000000000001> const, 0,
Eigen::OuterStride<-0x00000000000000001> > const,
-0x00000000000000001, -0x00000000000000001, false,
Eigen::Dense>::BlockImpl (
this=0x7fffffffe090, xpr=..., a_startRow=0, a_startCol=0,
blockRows=3, blockCols=140737488347168) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/Block.h:159
#16 0x00000000004127fd in Eigen::Block<Eigen::Ref<Eigen::Matrix<float,
6, -0x00000000000000001, 0, 6, -0x00000000000000001> const, 0,
Eigen::OuterStride<-0x00000000000000001> > const,
-0x00000000000000001, -0x00000000000000001, false>::Block
(this=0x7fffffffe090,
xpr=..., a_startRow=0, a_startCol=0, blockRows=3,
blockCols=140737488347168) at
/home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/Block.h:136
#17 0x0000000000412171 in
Eigen::DenseBase<Eigen::Ref<Eigen::Matrix<float, 6, -1, 0, 6, -1>
const, 0, Eigen::OuterStride<-1> > >::topRows (this=0x7fffffffdfd0,
n=3)
at /home/sbarthelemy/.local/share/qi/toolchains/linux64/eigen3/include/eigen3/Eigen/src/Core/../plugins/BlockMethods.h:268
#18 0x00000000004115e6 in main () at /home/sbarthelemy/ar/s/eigenref/main.cpp:46
#include <iostream>
#include <Eigen/Eigen>
#include <memory>
class Interface {
public:
virtual size_t size() const = 0;
virtual void compute() = 0;
virtual const Eigen::Ref<const Eigen::Matrix<float, 6, Eigen::Dynamic>, Eigen::Aligned> &
get() const = 0;
virtual ~Interface() {};
};
class Implementation10 : public Interface {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Implementation10() {};
size_t size() const {
return 10;
}
void compute() {
m_ = m_.Identity();
}
const Eigen::Ref<const Eigen::Matrix<float, 6, Eigen::Dynamic>, Eigen::Aligned> &
get() const {
return m_; // warning: returning reference to temporary
}
private:
Eigen::Matrix<float, 6, 10> m_;
};
Interface* createInterface() {
return new Implementation10();
}
int main()
{
std::cout << "Hello, world" << std::endl;
const std::auto_ptr<Interface> interface(createInterface());
Eigen::Matrix<float, 3, Eigen::Dynamic> triple(3, interface->size());
interface->compute();
triple = 3 * interface->get().topRows(3);
std::cout << triple;
return 0;
}