Re: [eigen] Subtle way to produce bugs when using Block |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Subtle way to produce bugs when using Block
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Fri, 13 Nov 2009 15:27:27 -0500
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=MLmGIqcqzbbp/MXUWZUonJpyB0QjDLqdXt+Ad9kyfFQ=; b=yAQZie5adgQkQBIjcCQ9sH2zjWsXzLlvxsZnr7phiOErRZHH6GHeIyogn1N9xuyMqo pTLB3MLCH3+2a+s5Sdz5XBJQ/0PKfvauxyWCjKfj5lx2Sgiv3DoPUqkSSUUe0P7GNvsZ Z5b6muecGve7HedKpcmi2VMfF2kEpe1Wo3Yp0=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=mnIR6ezxEMzBbCH1nuVsT+F4x3mT+2A6oY0b1dSWIQ63HYXvj6n1jCdJ+DUxFqySMD Z17t/UNYTYx4LSZ9ThUN9nHErJLoH0U0QhQ6sgRiloYVbF/9to53GCfxGjdKMitylld6 SAR9dI3A14F+DJGHc890BLYPi2466cuT6l+Ew=
2009/11/13 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
>
> On Fri, Nov 13, 2009 at 2:25 PM, Márton Danóczy <marton78@xxxxxxxxx> wrote:
>>
>> Hi,
>>
>> I've encountered some (possibly not so?) weird behaviour when keeping
>> references to blocks:
>>
>> template <typename X>
>> void f(const MatrixBase<X>& x)
>> {
>> typedef typename Block<X, ei_traits<X>::RowsAtCompileTime, 1> col_t;
>>
>> for (int i=0; i<x.cols(); ++i)
>> {
>> //using this line produces strange (undefined) results
>> col_t xi(x, i);
>
> this is because the ctors of Block<X, ...> expect a const X& and the class
> Matrix has a non explicit ctor from any MatrixBase<> object. So if the type
> of X is Matrix, then x is implicitely evaluated to a temporary Matrix
> object... One global solution to detect this mistake at compile time (and
> abord compilation) would be to make this Matrix's ctor explicit. But then if
> someone write a function expecting a Matrix, e.g.:
>
> void foo(const MatrixXf& x);
>
> then the following wont work:
>
> foo(a+b);
Indeed, so we really can't do that solution.
>
> The user would have to explicitely write either:
>
> foo((a+b).eval());
> foo(MatrixXf(a+b));
>
> I'm not saying that's a bad solution, but I'm sure many users will find this
> behavior cumbersome.
>
> So, the other solution is to generalize what Benoit did for the Replicate's
> ctor to all expressions. The principle is to make the expression ctor
> generic on the nested expression type and explicitely check that the given
> type and the expected type are the same. Perhaps we could also allow to
> automatically cast a MatrixBase<X> to X, that would make "col_t xi(x, i);"
> work as expected.
You mean casting _references_ without constructing a separate object
of X? How do you do that in a way that's guaranteed to work (i.e.
guaranteed to cast the reference without constructing a separate
object) ?
Otherwise, yes one can do as in Replicate.
Benoit
>
> Gael.
>
>>
>> //this is the correct way to do it:
>> col_t xi(x.derived(), i);
>>
>> do_something(xi);
>> }
>> }
>>
>> It was quite hard to hunt down this bug. Apart from that I don't
>> understand what's happening here, is there a way to prevent the user
>> from making this mistake?
>>
>> Thanks,
>> Marton
>>
>>
>
>
>