This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++11 (abridged version)


Since some felt that C++11 might have not been discussed sufficiently,
I thought I'd try to summarize the recent discussions, and present
my view condensed in a single email.  Please read until the
end before replying. :-)

On C++11
--------

Now that gdb 7.12 is out, master has switched to requiring a C++03
compiler.  The original plan, which we have been following, was to
stay within C++03:

  https://sourceware.org/gdb/wiki/cxx-conversion

Over the past weeks, patches actually making use of C++ started
appearing on the lists, and the subject of how C++11 would simplify
things came up, multiple times.

A couple weeks ago, I sent a patch to add an owning smart pointer to
GDB.  I chose to model the interface on C++11's std::unique_ptr.  For
that reason, our version is called gdb::unique_ptr.  My patch went a
step further, and made gdb::unique_ptr be an alias for std::unique_ptr
if compiled with a C++11 compiler.  See the version that landed in the
tree at <https://sourceware.org/ml/gdb-patches/2016-10/msg00506.html>,
which contains the clearest commit log / introduction.

A large discussion around that patch followed [1], circling around a
few related points:

#1 - whether we should be reimplementing C++11 features.

#2 - whether we should be taking advantage of C++11 features when
     available, provided we have C++03 fully functional fallbacks in
     place.  (and then generically, $version+1 features provided we
     have $version fallbacks.)

#3 - whether we should instead switch to require a C++11 compiler

#4 - if so, then what is the policy to accept the next standard
     versions going forward.

I'll expand on each of those points below, presenting my opinions
and suggested way forward.

On #1, my opinion is yes.  It makes total sense IMO to model
APIs/features on what the standard ends up with, in order to ease
future transition to a newer standard requirement, and also to
leverage the learning and reference material found throughout the
internet, dedicated to standard C++.  That's assuming that the
standard APIs in question are a good fit for the use case in question,
of course.  Here I'm thinking of small utility routines, like
std::to_string, or some metaprogramming helpers (traits), and things
like that.  Aiming at designing APIs compatible with the standard
library algorithms should go without saying.

On #2, I think it depends.

Sprinkling random code throughout with #ifdef __cplusplus >= $ver
should be out of question.  I don't think anyone would seriously
propose that.

Cases like taking advantage of new keywords to catch problems at
compile time I think are no brainers.  For example C++11
final/override.  A similar case would be to take advantage of being
able to mark code as "constexpr".  Going forward, C++14 allows
constexpr in more cases, so even before requiring C++14, I could see
us adding a CONSTEXPR14 define that compiles out to nothing if the
compiler doesn't support it, just like the FINAL/OVERRIDE macros.  I
don't have a use case in mind, but if it appears, I don't think we
should prohibit it.  Yet another example would be C++17 attributes,
which are mostly the same as GCC's __attribute__, except standard.

Otherwise, if talking about standard library features, I think that if
the conditional compilation is done inside some central gdb utility
routine, and, it gives some great advantage, then I think yes.
Otherwise, no.

The case of using C++11's std::unique_ptr, which enforces move
semantics using rvalue references, and uses SFINAE to only allow safe
conversions (catching them at compile time), is an example of "great
advantage".  It would be possible to implement or closely emulate
these things in C++03, but it'd not be trivial code.  People were
already calling my unique_ptr "boost-like", even though it's actually
a very simple smart pointer.  Much simpler to punt on the
complications, and just rely on a real C++11 compiler to catch
problems at compile time.  I can't think of another example like
this though.  I think these cases must be evaluated on a case by
case basis, with the default being "don't do it".  The std::unique_ptr
case is special because an owning pointer will naturally be used
pervasively.

My opinion on #3 (should we require C++11 now), is yes.  C++11 is a
great step up from C++03, and being able to use it fully would result
in a more efficiency gdb, and would also allow simplifying things that
require ugly workarounds in C++03.  I.e., if you hate C++ and you think
it's messy, it may actually be that what you hate is C++03, and that you'd
actually like C++11 if you give it a chance.  E.g., rvalue references, efficient
move-aware containers (also allowing us to make containers "own" the containing
objects, resulting in even simpler code), template aliases, variadic templates,
etc. etc.  C++11 would avoid having to consider reimplementing basic utilities
like e.g., a type-safe hash table.  C++11 is also a _simpler_ language in a way,
as some ugly warts have been ironed out in the language (e.g., std::string
and contiguous buffer guarantees).


On #4 (policy for newer standard versions), as I've been saying many
times in the past week, I think that what matters is whether there's
reasonably widespread compiler availability, meaning the latest stable
releases of distributions include a compiler for the standard, or it's
easy to get one by installing some optional package.  If reasonably
available, then we should switch, and take advantage of the great work
our compiler and standards friends have been doing.  If OTOH we require
every GDB developer and integrator to build a compiler first before building
gdb, then that is too inconvenient and we shouldn't switch yet.  I
don't think, however, that the rarer use case of wanting to build a
new gdb on an old/ancient distro to debug programs built with an old
compiler should hold us back.  For those rarer cases, I think it's OK
if you'd need to build a compiler first.  Failing that, you can still
use remote debugging with new gdb on a separate machine against
old gdbserver on old machine.  Or failing even that, there's always
old gdb, which is not going away..

On GCC, full C++11 support started with GCC 4.8.  And, from the past
week's discussions, I think that it became clear that at least GCC 4.8
is easily available one way or another on (at least) the latest
stable release of all the major GNU/Linux distros.  BSDs have clang
versions available that support C++11 too, either as system compiler
or as a package in ports.  For Windows/mingw/mingw-w64, again there are
binaries easily available.  Etc.  In practice, most people are actually
building GDB with newer compilers even.  And, many have actually been
building GDB as as a C++14 program for a while, because GCC 6.1 switched
the default C++ dialect to C++14...

One related potential blocker that I saw was whether the buildslaves
in our buildbot were ready for the conversion.  As you can see in this
thread <https://sourceware.org/ml/gdb-patches/2016-10/msg00488.html>,
I believe we're now ready on that end too.

Going forward past C++11, since "reasonable availability" is not
quantifiable, Eli suggested the policy of

  "(...) waiting until the oldest compiler which supports that newer
  standard is at least 3 years old (like GCC 4.8.1 is today)."

And I agree with that.  (I'd prefix it with "at least".)  

Of course, even policies can be re-discussed later, so we shouldn't feel
trapped on past decisions, but, I think that that's a reasonable starting
guideline, and having it clearly written somewhere is more transparent,
which definitely a good thing in my view.

At this point, I find myself in an odd position --- several people
have been telling me offlist how they wanted C++11 like yesterday already.
There was support in last week's discussions as well.  OTOH, I'm not
sure whether I can assume that silence on the list means "go ahead".
So I think I'll need to call a bold move and say that if there are no
actual identified blockers, or if people reply to this email with
approval, I'm going to proceed with the straw man 'path toward
C++11' proposal at
<https://sourceware.org/ml/gdb-patches/2016-10/msg00381.html> real
soon.

[1] - most of the discussion happened in two threads here:

 - https://sourceware.org/ml/gdb-patches/2016-10/msg00223.html
 - https://sourceware.org/ml/gdb-patches/2016-10/msg00341.html

Thanks,
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]