Boost logo

Boost Users :

From: Martin Apel (martin.apel_at_[hidden])
Date: 2008-06-16 05:01:20


Joel de Guzman wrote:
> Martin Apel wrote:
>
>> Hi all,
>>
>> I posted this issue a week ago to the Spirit mailing list only, but I
>> got no reply. So I repost this onto the Boost mailing list as well:
>>
>> I tried to compile a Spirit grammar parsing a real number using closures
>> under Microsoft Visual C++ 2005. The same grammar compiles fine on Linux
>> using GCC 4.x. Boost version is 1.35.0 in both cases. As far as I
>> understood, the error is caused by an assertion inside the closure class
>> template:
>> closure_frame_t& context() { assert(frame!=0); return
>> frame.get(); } (line 352 of
>> boost/spirit/phoenix/closures.hpp)
>>
>> Even if I define NDEBUG, Phoenix closures don't compile, because the
>> return statement after the assertion returns a pointer to a
>> closure_frame_t and not a reference. From my point of view, this is not
>> really a compiler issue, but a bug in the header file
>> boost/spirit/phoenix/closures.hpp. I do not understand, why GCC compiles
>> this without any errors, because I think the code should not compile at all.
>> Any help would be appreciated.
>>
>
> Please post a minimal cpp file that exhibits the problem.
> Please try to make it as minimal as possible so as to
> focus on the problem. At any rate, have you read the
> FAQ:
>
> http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/faq.html#frame_assertion
>
> Regards,
>
Hi all,

the mentioned FAQ entry is about an assertion triggered at runtime, but
I don't even come that far, because the problem happens
at compile time. While trying to generate a small example, I found out,
what is causing the problem:
I marked the grammar class using the closure with __declspec(dllexport),
which causes MSVC to instantiate all members of a template,
even if they are never needed. It seems that otherwise the "context"
member function is never instantiated.
If you remove the __declspec(dllexport), everything compiles. I still
think, that the code is wrong, because it returns a pointer, where it
should return a reference. I have attached a small example, which
triggers the problem.

By the way, the example implements a real parser, which uses the
standard C++ runtime to convert the real number into a double. I had to
implement this,
because I found out, that the Spirit real_p parser creates numerically
different results from the standard runtime, i.e.
parsing the string "1.8" delivers a number like 1.8000000532 using
Spirit, while the C++ runtime delivers something like 1.7999999973,
which is always closer
to the real value. Please note, that these numbers are not accurate,
they are simply meant to demonstrate, what I mean.

Regards,

Martin




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net