blitzpp / blitz

Blitz++ Multi-Dimensional Array Library for C++
https://github.com/blitzpp/blitz/wiki
Other
405 stars 84 forks source link

docs: mention the safeToReturn() logic #57

Open slayoo opened 5 years ago

slayoo commented 5 years ago

Migrated from: https://sourceforge.net/p/blitz/bugs/40/

Here's a recipe to show how Blitz misbehaves with a call to a C++11 auto/decltype function: Same results with recent versions of g++ and clang++

$ cat test.cpp
#include <blitz/array.h>
using namespace blitz;
struct cls
{
#define decltype_return(expr) -> decltype(expr) { return expr; }
auto half(const Array<double, 2> &B, const Range &i, const Range &j)
#ifdef SKIPHALF
decltype_return(B(i,j))
#else
decltype_return(.5 * B(i,j))
#endif

void substract_half(
const Array<double, 2> &A, const Array<double, 2> &B,
const Range &i, const Range &j
)
{ A(i,j) -= half(B,i,j); }
};
int main() {
Range i(0,2), j(0,4);
Array<double, 2> A(i,j), B(i,j);
A = 10;
B = 20;
cls op;
op.substract_half(A,B,i,j);
std::cerr << A << std::endl;
}

$ g++ -std=c++0x -DBZ_DEBUG -lblitz test.cpp
$ ./a.out
/opt/local/include/blitz/shapecheck.h:73 Incompatible shapes detected:
(3,5)
(1606416304,32767)

[Blitz++] Shape check failed: Module /opt/local/include/blitz/globeval.cc line 152
Expression: (s*A)
Assertion failed: (0), function _bz_evaluate, file /opt/local/include/blitz/globeval.cc, line 168.
Abort trap

$ g++ -std=c++0x -DBZ_DEBUG -lblitz test.cpp -DSKIPHALF
$ ./a.out
(0,2) x (0,4)
[ -10 -10 -10 -10 -10
-10 -10 -10 -10 -10
-10 -10 -10 -10 -10 ]

That is, if the half() function contains an expression including multiplication by a constant, the array ranges seem to be uninitialised (i.e. the 1606416304 & 32767 values).

Quoting Patrik's comment from the mailing list:

the array you're generating with B(Range) goes out of scope, so the expression is pointing to an array that no longer exists. There is a way to make the expression hold a copy of the Array instead of a reference by using the function safeToReturn(expr).

The safeToReturn() logic is not documented anywhere.