From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 84930 invoked by alias); 20 Oct 2016 17:08:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 84920 invoked by uid 89); 20 Oct 2016 17:08:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=widespread, naturally, appearing, trapped X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Oct 2016 17:08:01 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F13EF4E4E5 for ; Thu, 20 Oct 2016 17:07:59 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9KH7wuw010951 for ; Thu, 20 Oct 2016 13:07:59 -0400 To: GDB Patches From: Pedro Alves Subject: C++11 (abridged version) Message-ID: <4300d24a-8711-c5de-79ce-7c530162288c@redhat.com> Date: Thu, 20 Oct 2016 17:08:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-10/txt/msg00607.txt.bz2 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 , 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 , 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 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