ukoethe / vigra

a generic C++ library for image analysis
http://ukoethe.github.io/vigra/
Other
407 stars 191 forks source link

Problem with Shape1 #480

Open friedrichromstedt opened 4 years ago

friedrichromstedt commented 4 years ago

While acquainting myself with Vigra, I stumbled upon some problem with 1-dimensional MultiArrays.

I am trying to initialise MulitArray<1, float> with Shape1(<length>). <length> is either a plain number, or the name of an integer variable.

The initialisation works fine when using a literal number, but fails in the end when using a variable.

I am providing below a small code to reproduce the behaviour.

The compiler in use is VS 2019, using the VS 2015 (v140) toolset, with target platform 10.0.18362.0.

In the code below, the second paragraph in int main() is the most relevant. Both initialisation of MultiArray<1, float> compile fine, also the one referencing a non-existing variable named xyz. However, the commented-out code path in the middle of the paragraph does not compile. Notice also that the two initialisation lines yield warnings (these are in German):

1>Shape1.cpp(12): warning C4930: "vigra::MultiArray<1,float,std::allocator<float>> shape1br(vigra::Shape1)": Funktion mit Prototyp wurde nicht aufgerufen (war eine Variablendefinition gemeint?)
1>Shape1.cpp(14): warning C4930: "vigra::MultiArray<1,float,std::allocator<float>> shape1cr(vigra::Shape1)": Funktion mit Prototyp wurde nicht aufgerufen (war eine Variablendefinition gemeint?)

Telling (approx.): Function with prototype has not been called (was meant a variable definition?)

Things are working as expected with two-dimensional MulitArrays, as demonstrated in the last two paragraphs of the main function. Also the first paragraph using a verbatim number as argument for Shape1 yields no surprises.

This is with Vigra-1.11.1; I tried also with a github version from 2020-08-12, ending up with the same results.

The test code is:

#include <iostream>
#include <vigra/multi_array.hxx>

using namespace std;
using namespace vigra;

int main() {
    MultiArray<1, float> shape1ar(Shape1(42));
    cout << "shape1ar.shape() = " << shape1ar.shape() << "." << endl;

    int length = 43;
    MultiArray<1, float> shape1br(Shape1(length));
    // cout << "shape1br.shape() = " << shape1br.shape() << "." << endl;  // <== error happens here
    MultiArray<1, float> shape1cr(Shape1(xyz));

    MultiArray<2, float> shape2ar(Shape2(5, 7));
    cout << "shape2ar.shape() = " << shape2ar.shape() << "." << endl;

    int width = 10, height = 11;
    MultiArray<2, float> shape2br(Shape2(width, height));
    cout << "shape2br.shape() = " << shape2br.shape() << "." << endl;
}
hmeine commented 4 years ago

I always hated these cases where the compiler misinterprets an "obvious" syntax for some other syntax; C++ is simply too complex…

I would probably work around that by instantiating a Shape1 variable, instead of an int variable. Maybe someone else (Ulli?) knows other ways to make the line (which you could helpfully mark with a // <== error happens here comment BTW) work.

PS: Tip of the day for getting English messages for bug reports etc.: Prefix your command (here make) with LANG=C.

friedrichromstedt commented 3 years ago

I would probably work around that by instantiating a Shape1 variable, instead of an int variable. Maybe someone else (Ulli?) knows other ways to make the line (which you could helpfully mark with a // <== error happens here comment BTW) work.

Instantiating a Shape1 variable and using this during instantiating the MultiArray<1, float> works for me. Thanks for the hint!

int length = 43;

Shape1 shapedr(length);
MultiArray<1, float> shape1dr(shapedr);
cout << "shape1dr.shape() = " << shape1dr.shape() << "." << endl;

I've edited my post to include the comment you proposed.

PS: Tip of the day for getting English messages for bug reports etc.: Prefix your command (here make) with LANG=C.

Well, I am using Visual Studio here ...

Friedrich