On 4/11/12, Richard Guenther <richard.guent...@gmail.com> wrote:
> On Apr 11, 2012 Lawrence Crowl <cr...@google.com> wrote:
> > On 4/10/12, Jakub Jelinek <ja...@redhat.com> wrote:
> > > That when stepping through code in the debugger you keep
> > > enterring/exiting these one liner inlines, most of them
> > > really should be at least by default considered just as normal
> > > statements (e.g. glibc heavily uses artificial attribute for
> > > those, still gdb doesn't hide those by default).
> >
> > You do want to step into those inline functions, except when
> > you do.  In the short term, we can make the debugger behave
> > as though they did not exist.  In the longer term, we really
> > want debugging tools that help C++ programmers.  One way to
> > get there is to use C++ ourselves.
>
> Fix the debugger first please.

And when the debugger says "show us you're using C++ first", what do
we do?  Based on discussions that I have had, this problem is real.

> > > > The above is just quickly cooked up examples. A carefully
> > > > designed C++ based API can be self documenting and make
> > > > the client code very readable. It is hard to believe that
> > > > there is no room for improvement in GCC.
> > >
> > > Do you have examples?  E.g. I haven't touched gold, because,
> > > while it is a new C++ codebase, looks completely unreadable to
> > > me, similarly libdw C++ stuff.  A carefully designed C based
> > > API can be self documenting and make the code very readable
> > > as well, often more so.
> >
> > If you just look at any decently sized code base, it'll look
> > pretty much unreadable.  The question is how quickly can
> > someone who learns the base vocabulary can produce reasonable
> > modifications.
> >
> > There are many places where C++ can help substantially.
> > For example:
> >
> > () The C++ postfix member function call syntax means that
> > following a chain of attributes is a linear read of the
> > expression.  With C function call syntax, you need to read the
> > expression inside out.
>
> It's a matter of what you are used to (consider LISP).

Certainly.  When I was learning to ride horses, every time I would
get comfortable, my instructor would say, now do it this other way.
It was very uncomfortable, but I got over that and improved my
riding.  I went through that same transition when I was switching
to C++.

> > () C++ has both overloaded functions and member functions,
> > so you can use the same verb to talk about several different
> > kinds of objects.  With C function names, we have to invent
> > a new function name for each type.  Such names are longer and
> > burden both the author and the reader of the code.
>
> Agreed.  Function overloading is one of the nice things that
> does not automatically make the code-base look "partial C++".
> Likewise operator overloading can make things like
>
> bit_offset = double_int_add (bit_offset,
>     tree_to_double_int (DECL_FIELD_BIT_OFFSET (field)));
>
> be just
>
> bit_offset = bit_offset + DECL_FIELD_BIT_OFFSET (field);
>
> it still looks like C but with some C++ "magic".
>
> > () Standard C++ idioms enable mashing program components
> > with ease.  The C++ standard library is based on mixing and
> > matching algorithms and data structures, via the common idiom
> > of iterators.
>
> Sort-of agreed.  Though iterator-style (and more so functor style)
> was never one of my favorite.
>
> > () The overloadable operator new means that memory can be
> > _implicitly_ allocated in the right place.
>
> Implicit allocation is bad.  In a compiler you want to _see_
> where you spend memory.

The operator new is explicit, but the source of the memory for
that allocation is implicit.  You want to be able to _change_
where you allocate memory without touching half the source base.
Operator new overloads enable that precisely because you do not
have to say where the memory comes from each time you allocate.

> > () Constructors and destructors reduce the number of places in
> > the code where you need to do explicit memory management. Without
> > garbage collection, leaks are less frequent.  With garbage
> > collection, you have much less active garbage, and can run
> > longer between collection runs.  Indeed, a conservative collector
> > would be sufficient.
>
> Time will tell.
>
> > () Constructors and destructors also neatly handle actions that
> > must occur in pairs.  The classic example is mutex lock and
> > unlock.  Within GCC, timevar operations need to happen in pairs.
>
> Agreed.
>
> > () Class hierarchies (even without virtual functions) can
> > directly represent type relationships, which means that a
> > debugger dump of a C++ type has little unnecessary information,
> > as opposed to the present union of structs approach with
> > GCC trees.
>
> In GCC trees only the "base" is a union, and it is so as
> implementation detail.  That gdb does not grok a 'tree' well is
> because gdb is stupid.  All the information is there.

It is an implementation detail that causes friction with the
programming environment.

> > () Class hierarchies also mean that programmers can distinguish
> > in the pointer types that a function needs a decl parameter,
> > without having to say 'all trees' versus 'a very specific tree'.
> > The static type checking avoids run-time bugs.
>
> True.  In a very limited set of cases.  C++ is not powerful enough to
> express pointer-to-everything-that-would-be-considered-a-gimple-val.
> Maybe C++ is not the right choice after all?  (I suppose C++ concepts
> would have helped here? pointer-to-tree-that-fulfils-is_gimple_val
> ...  (though is_gimple_val is not be a static property).
>
> > I have written compilers in both C and C++.  I much prefer
> > the latter.
>
> Did you ever try to convert an existing large C codebase to C++?
> I would not expect a very good result and rather start from
> scratch.  So I don't see that we ever arrive (or want to arrive)
> at a pure C++-style GCC.  Instead I expect we end up (and desire
> to end up) with GCC compiled with a C++ compiler that uses C++
> features to make the existing style more readable and maintainable.

While I didn't start the process, I have worked on a C++ compiler
that was in transition from a C source base to a C++ source base.
The parts of the compiler that didn't need much attention still
had a C style.  The parts that did need attention, or provided
immediate benefit, changed to a C++ style fairly rapidly.  Even so,
after more than a decade, the compiler had a mix of styles.  For all
I know, it may still have a mix.

One of the changes I made was to convert an enum into a class
with member functions, etc.  The functional change required more
information than the enum could represent.  The enum was passed in
a single register, while the class was copied for each parameter.
Assignment changed from register-to-register into memcpy.  So,
the instruction overhead for this type jumped substantially.
After 20,000 lines modified in this change, I benchmarked the
compiler and it was 1% faster.  Yes, faster.  The reason is that in
the process I reorganized the associated parsing and error checking.
I took a micro-optimization hit, but won a bigger macro-optimization.

The essential benefit of C++ is that it is easier to write and
use good abstractions, which enables higher-level changes for
higher-level effects.

-- 
Lawrence Crowl

Reply via email to