[RFA 6/8] Use value_freer in dwarf2_evaluate_loc_desc_full

Pedro Alves palves@redhat.com
Tue Dec 20 14:49:00 GMT 2016


On 12/13/2016 01:28 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> 
> Pedro> Or "reset ()", following the naming used in the standard smart pointers?
> 
> I went with reset since I think "free" can be a macro sometimes.
> Or at least it could in C... not actually sure if C++ removed this
> possibility.

I always assumed it has, but had never went looking for the specific
wording.  Looking at the C++14 draft N4140, I see:

 17.6.1.2 - Headers:

 5 - Names which are defined as macros in C shall be defined as macros in
 the C ++ standard library, even if C grants license for implementation 
 as functions. [ Note: The names defined as macros in C include the
 following: assert, offsetof, setjmp, va_arg, va_end, and va_start. - end note ]

 6 - Names that are defined as functions in C shall be defined as functions in
 the C ++ standard library." (175)

And then footnote 175 clarifies:

 "175) This disallows the practice, allowed in C, of providing a masking
 macro in addition to the function prototype. The only way to achieve equivalent
 inline behavior in C ++ is to provide a definition as an extern inline function."


So I think the answer is yes, C++ removes that possibility.


BTW, I meanwhile realized that "release" would also be a
naming/concept conflict with release_value / value_release_to_mark
too.  Really best to avoid it here.

In pondering a bit more over this, I wonder whether
adding a "scoped_" to go with scoped_restore etc., would make
it a bit clearer to readers that this is a RAII type.  Then
also considering value_release_to_mark, I wonder would an
API/naming like this:

struct scoped_value_mark
{
   scoped_value_mark () : m_value (value_mark ()) {}
   ~scoped_value_mark () { free_to_mark ()}

   void free_to_mark () { if (m_value) value_free_to_mark (m_value); }
   void release_to_mark () { if (m_value) value_release_to_mark (m_value); }

   /* Get the mark value.  */
   struct value *get () { return m_value; }
};

Uses would look like:

 scoped_value_mark value_mark;
 ...
    value_mark.free_to_mark (); // some path than wants an explicit "free_to_mark".


In eval.c:fetch_subexp_value we'd use it like:

  /* Evaluate the expression.  */
  scoped_value_mark mark;

  [...]
      result = evaluate_subexp (NULL_TYPE, exp, pc, EVAL_NORMAL);
  [...]

  new_mark = value_mark ();
  if (mark.get () == new_mark)
    return;

  /* Make sure it's not lazy, so that after the target stops again we
     have a non-lazy previous value to compare with.  */
  [...]

  if (val_chain)
    {
      /* Return the chain of intermediate values.  We use this to
	 decide which addresses to watch.  */
      *val_chain = new_mark;
      mark.release_to_mark ();
    }
}

Would this result in clearer client code?  IMHO, yes, but WDYT?

Thanks,
Pedro Alves



More information about the Gdb-patches mailing list