Hans Åberg wrote:

> > On 13 Mar 2018, at 23:23, Frank Heckenbach <f.heckenb...@fh-soft.de> wrote:
> > 
> >> Bison 3.0.4 marks the constructor for the syntax_error class as 'inline'
> >> when generating a C++ scanner, which results in undefined references when
> >> the exception is thrown from a separate scanner file. Since this is the
> >> stated purpose of the syntax_error class (see
> >> http://lists.gnu.org/archive/html/help-bison/2013-07/msg00010.html), this
> >> appears to be a bug.
> > 
> > Anyway, do you use the "--defines" option or "%defines" setting to
> > generate a header that you include in your other source files? If
> > so, AFAICS, the inline constructor is generated in the same header,
> > so it should be available in your other source file, too.
> 
> It ends up in the .cc file even with %defines, it seems. But it
> should properly be in the header file, and probably the other
> inlines too.

I checked it and found that it's only put in the header if

  %define api.token.constructor

is set. But that can only be set if

  %define api.value.type

is also set. So this indeed seems to be wrong for non-variant users.

Instead of removing "inline" as suggested in the other bug report
(which would then break with api.token.constructor), the following
patch will always put the definition in the header.

I will apply this patch in my C++17 version, but since I'm not a
Bison maintainer, I can't promise it will go in the C++98 parser, or
in the official Bison sources at all. For now, you can apply the
patch manually (your installation directory may vary).

Regards,
Frank

--- /usr/share/bison/c++.m4
+++ /usr/share/bison/c++.m4
@@ -161,7 +161,10 @@
     /// Syntax errors thrown from user actions.
     struct syntax_error : std::runtime_error
     {
-      syntax_error (]b4_locations_if([const location_type& l, ])[const 
std::string& m);]b4_locations_if([
+      syntax_error (]b4_locations_if([const location_type& l, ])[const 
std::string& m)
+                   : std::runtime_error (m)]b4_locations_if([
+                   , location (l)])[
+      {}]b4_locations_if([
       location_type location;])[
     };
 
@@ -279,13 +282,7 @@
 # ----------------------
 # Provide the implementation needed by the public types.
 m4_define([b4_public_types_define],
-[[  inline
-  ]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const 
location_type& l, ])[const std::string& m)
-    : std::runtime_error (m)]b4_locations_if([
-    , location (l)])[
-  {}
-
-  // basic_symbol.
+[[// basic_symbol.
   template <typename Base>
   inline
   ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()

Reply via email to