help-bison
[Top][All Lists]
Advanced

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

Re: Growing stacks in C++


From: Hans Aberg
Subject: Re: Growing stacks in C++
Date: Fri, 23 Jul 2010 00:33:18 +0200

On 23 Jul 2010, at 00:00, Paul Hilfinger wrote:

One problem is that the C stack does not call C++ copy constructors
when reallocating. So one can only use a POD semantic value.

I was indeed aware of the non-POD issue. However, this problem already prevents the use of %union in C++ files if any members have constructors
or destructors.  If one uses a %union that is legal for C++, is there
any other issue that prevents expansion of stacks?  I intend to remove
the __cplusplus test for exandability in glr.c.

There was an effort (or so I remember) to write a C-skeleton for compilable under C++, but it is was abandoned, being too complicated.

But you have phrased is as an all through C program compiled as C++.
That must work if the C parser and the program is written in the
subset common to C++.

So I would assume.  The documentation, therefore, seems to be slightly
misleading when it says:

  Because of semantic differences between C and C++, the deterministic
  parsers in C produced by Bison cannot grow when compiled by C++
compilers. In this precise case (compiling a C parser as C++) you are
  suggested to grow `YYINITDEPTH'.  The Bison maintainers hope to fix
  this deficiency in a future release.

This is a bit mysterious. I think the problem was namespace issues - under C++ some names should be in std. I looked into the C-code, and it just doubles the array and then memcpy's over the data. Can't see why that wouldn't grow under C++.

I suggest the paragraph be modified to say "when the semantic types have
constructors or destructors" or something of the sort.

Best if Akim or Paul Eggert get back on this.

BTW: I observe that ISO C++ has a template function
std::uninitialized_copy, defined in <memory>, which ought to work for
copying a stack properly.

The algorithm is
  for (; first != last; ++result, ++first)
   new (static_cast<void*>(&*result))
    typename iterator_traits<ForwardIterator>::value_type(*first);

So it looks as it allocates for each iterator value, which isn't right. The C skeleton allocates a new block and then memcpy's over the data. Here one should iteratively call the copy-constructors. Then it might be easier to use std::vector or std::deque. Then using the C- skeleton start becoming complicated.

  Hans





reply via email to

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