compiling error for vector(M)

1 view
Skip to first unread message

Jiqiang Guo

unread,
Feb 6, 2012, 1:10:27 PM2/6/12
to stan development mailing list
In example vol2/jaws, I have

transformed parameters {
vector(M) mu;
for (m in 1:M) mu[m] <- beta0 + beta1 * age[m];
}

where M is defined in the Data block.

The cpp code could not be compiled here though it works if it is
`vector(4) mu.'

--
Jiqiang

Bob Carpenter

unread,
Feb 6, 2012, 2:17:43 PM2/6/12
to stan...@googlegroups.com
Believe it or not, there's an entire Wikipedia
page devoted to this "feature" of the C++ parser
and its unexpected consequences:

http://en.wikipedia.org/wiki/Most_vexing_parse

As the Wikipedia says, Clang gives a good error
message, which is how I found the Wikipedia entry:

src/demo/jaws.cpp:183:20: warning: parentheses were disambiguated as a
function declarator
vector_v mu(vector_v(M));

Eh?

Lucky for us, the Wikpedia describes the magic
pixie dust required to get a more reasonable
behavior out of the constructor. A magic layer of
parens:

vector_v mu((vector_v(M)));

I'll commit a fix to the code generator ASAP.

The web is so awesome.

- Bob

P.S. reminds me of Boost's recommended disambiguation
of isnan as (boost::math::isnan)(x) so that "isnan"
isn't expanded as a macro.

Bob Carpenter

unread,
Feb 6, 2012, 3:49:46 PM2/6/12
to stan...@googlegroups.com
I just committed a patch, so the BUGS
Jaws model now compiles as it was.

- Bob

On 2/6/12 1:10 PM, Jiqiang Guo wrote:

Jiqiang Guo

unread,
Feb 6, 2012, 4:40:15 PM2/6/12
to stan...@googlegroups.com
Thanks.  The fix might introduce a problem.  Please see for example vol2/mvn_orange:

mvn_orange.cpp:229:39: warning: expression result unused [-Wunused-value]
            vector<vector<var> > phi((K,vector<var>((3))));
                                      ^
mvn_orange.cpp:229:34: error: no matching constructor for initialization of 'vector<vector<stan::agrad::var> >'
            vector<vector<var> > phi((K,vector<var>((3))));
                                 ^   ~~~~~~~~~~~~~~~~~~~~

--
Jiqiang 

Bob Carpenter

unread,
Feb 6, 2012, 4:56:22 PM2/6/12
to stan...@googlegroups.com
Thanks for pointing this out and sorry for
putting you through this -- we should have better
tests in place for the existing models compiling.

I'll sort out the difference between the base
case and the recursion and get just the right
number of extra parens.

- Bob

Bob Carpenter

unread,
Feb 6, 2012, 8:47:36 PM2/6/12
to stan...@googlegroups.com
Variable declarations were trickier than I thought, but the bugs
in variable declaration generation that Jiqiang
found (see mail chain below) are now patched and the compiled
models are now parsing for:

src/models/bugs_examples/vol2/jaws/jaws.stan
src/models/bugs_examples/vol2/mvn_orange/mvn_orange.stan

----------------

The following details are probably only interesting if
you spent the last few hours with pencil and paper and
C++ compiler.

After fixing the "most vexing parse", the problem with
which is that

var a(var());

isn't taken as an initialization of a to var(), I
introduced a simpler, but related parsing ambiguity,
which Jiqiang also found:

var a(); // variable a of type var
// initialized with nullary constructor var()
var b = a; // OK

double a(); // a declared as nullary function returning double
double b = a; // DOH!

What I needed was a slightly more nuanced base case
for the recursive generation of types:

var a(var()); // copy constructor
var b = a; // OK

double a(double()); // init to default 0
double b = a; // OK

but that was too ugly to bear, so I cleaned up the
base case so the declarations are the way I'd write
them by hand (now that I understand the ambiguities
mentioned above):

var a; // variable a of type var init with nullary ctor var()
var b = a; // OK

double a; // declaration of variable a
double b = a; // OK

- Bob


On 2/6/12 4:40 PM, Jiqiang Guo wrote:

Reply all
Reply to author
Forward
0 new messages