inconsistent parser behaviour
Philipp Schwaha <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
Hi Guys,
I encountered inconsistent behaviour when refactoring a parser.
The extraction of the code is in the attachment and should be self
contained.
The essence is that I have a simple parser consisting of:
byte_(0xFF) >> byte_
It behaves differently depending on if this is passed into the parse
function inline or if it is returned via a function.
such as:
auto generate() -> decltype(byte_(0xFF) >> byte_) {
return (byte_(0xFF) >> byte_) ;
}
or wrapped in a function object:
struct dummy {
using type = decltype(byte_(0xFF) >> byte_) ;
type generate() const {
return (byte_(0xFF) >> byte_) ;
}
} ;
When testing using input of the form:
std::array<unsigned char, 2> const connect_test = { { 0xFF, 0x00 } } ;
the inline specification always succeeds parsing, but for the returned
values this is not (always) the case, surprisingly g++ and clang++ do
not agree on behaviour.
parse(start, end(connect_test), (byte_(0xFF) >> byte_)) ;
parse(start, end(connect_test), wrap.generate()) ;
parse(start, end(connect_test), generate()) ;
g++ -Wall -pedantic -std=c++11 submit.cpp -o submit && ./submit
inline
1 0
function object
0 2
function
0 2
clang++ -Wall -pedantic -std=c++11 submit.cpp -o submit && ./submit
inline
1 0
function object
1 0
function
0 2
I have the feeling I'm going into undefined behaviour land somewhere.
Any ideas what I missed and how to get consistent behaviour, preferably
so that it parses successfully.
Cheers & thanks
Philipp
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
submit.cpp
(text/x-c++src, 1.2 KB)
#include <boost/spirit/include/qi_binary.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <array>
using namespace boost::spirit::qi ;
auto generate() -> decltype(byte_(0xFF) >> byte_) {
return (byte_(0xFF) >> byte_) ;
}
struct dummy {
using type = decltype(byte_(0xFF) >> byte_) ;
type generate() const {
return (byte_(0xFF) >> byte_) ;
}
} ;
int main() {
std::array<unsigned char, 2> const connect_test = { { 0xFF, 0x00 } } ;
{
std::cout << "inline\n" ;
auto start = begin(connect_test) ;
bool result = parse(start, end(connect_test), (byte_(0xFF) >> byte_)) ;
std::cout << result
<< "\t" << (end(connect_test) - start)
<< std::endl ;
}
{
std::cout << "function object\n" ;
dummy wrap ;
auto start = begin(connect_test) ;
bool result = parse(start, end(connect_test), wrap.generate()) ;
std::cout << result
<< "\t" << (end(connect_test) - start)
<< std::endl ;
}
{
std::cout << "function\n" ;
auto start = begin(connect_test) ;
bool result = parse(start, end(connect_test), generate()) ;
std::cout << result
<< "\t" << (end(connect_test) - start)
<< std::endl ;
}
}