$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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