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 ;
  }

}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.