[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bison 3.0.4 %destructor is c++ mode seems to be called even in the n

From: Kaz Kylheku
Subject: Re: bison 3.0.4 %destructor is c++ mode seems to be called even in the normal parse
Date: Thu, 18 Aug 2016 10:12:42 -0700
User-agent: Roundcube Webmail/0.9.2

On 18.08.2016 08:36, Min Wang wrote:

In bison 3.0.4, the %destructor seems to be called even in the normal parse

In your example program you are using "Variants" rather
than %union. That's a very special C++-specific Bison feature.

It seems that there is no reason to use %destructor if you're
using variants. If any of the variants are pointers, they can
just be smart pointers; they don't have to be low level pointers.

Can you confirm whether %destructor is still called in the
normal parse if instead of:

  %type <PROG*> PROG
  %type <ListExp*> ListExp

you use

  %union {
    ListExp *ListExp;

That is to say, is this a issue specific to variants, or does it
affect C++ parsers regardless of whether %union or variants
are used?

If under %union, %destructor is correctly called only during
error recovery (the issue is absent) then just use %union,
since all your semantic value types are pointers. Then be sure
you have all the right delete calls in your grammar actions.

If you use variants, it seems you can side-step the issue
by not using pointers. If the values are smart pointers,
then there is no problem, because a rule like:

   foo : bar { $$ = $1; }

will handle the transfer from $1 to $$ using the smart pointer
assignment operator, allowing $1 to then be safely destroyed
by its destructor.

It does seem that you have discovered at least this bug,
or deviation from documented behavior: when plain pointer types
are used in variant declarations in a C++ parser, and %destructor
is used to free them in all circumstances.

So for instance, suppose that we use the type <char *>,
and we have a %destructor which calls free. In a C parser,
we might just have this:

   foo : bar { $$ = $1; }  /* transfer ownership of pointer */

But under C++ Bison with variants, we must do:

   foo : bar { $$ = strdup($1); } /* $1 %destructor will kick in */

Or perhaps this will work:

   foo : bar { $$ = $1;
               $1 = NULL; } /* Spare $1 from jaws of %destructor */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]