Message ID | 20220712002527.417444-1-dmalcolm@redhat.com |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 76A973AA9835 for <patchwork@sourceware.org>; Tue, 12 Jul 2022 00:26:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 76A973AA9835 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1657585567; bh=Wv1z7ybxrgNOOxhb9LoGXYCbsN0f4Y/m3N3lgZwSb8I=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=n1s8LXGUxuBRnuJS+ZBcShyVHXb1qiMKuf8PHy3oTXHK42vCyxwlpXt/FGFdrFYih W83pQgFG+32E3y7Ux9xrhCOkzSSQTx6gO7+1k9A1cXSgKnRnIIg4HORzIiz51gNfBj hnH51o7OJKU7a2y0WhBfcAVtXaM5S30KEkIK0FMI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 1AA753AA88EB for <gcc-patches@gcc.gnu.org>; Tue, 12 Jul 2022 00:25:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1AA753AA88EB Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-183-oy2tZDL6M2-03-f-aWgzJw-1; Mon, 11 Jul 2022 20:25:36 -0400 X-MC-Unique: oy2tZDL6M2-03-f-aWgzJw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4D9DB101A54E; Tue, 12 Jul 2022 00:25:36 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.2.16.236]) by smtp.corp.redhat.com (Postfix) with ESMTP id 10D8F400EA82; Tue, 12 Jul 2022 00:25:35 +0000 (UTC) To: Jonathan Wakely <jwakely.gcc@gmail.com>, gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] Add gcc/make-unique.h Date: Mon, 11 Jul 2022 20:25:26 -0400 Message-Id: <20220712002527.417444-1-dmalcolm@redhat.com> In-Reply-To: <CAH6eHdSnGwtScODMveYha1S5WiDo6YsexN_pRqe9n4vq-Pmkig@mail.gmail.com> References: <CAH6eHdSnGwtScODMveYha1S5WiDo6YsexN_pRqe9n4vq-Pmkig@mail.gmail.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: David Malcolm via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: David Malcolm <dmalcolm@redhat.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
[1/2] Add gcc/make-unique.h
|
|
Commit Message
David Malcolm
July 12, 2022, 12:25 a.m. UTC
On Fri, 2022-07-08 at 22:16 +0100, Jonathan Wakely wrote: > On Fri, 8 Jul 2022 at 21:47, David Malcolm via Gcc <gcc@gcc.gnu.org> > wrote: > > > > std::unique_ptr is C++11, and I'd like to use it in the > > gcc/analyzer > > subdirectory, at least. The following patch eliminates a bunch of > > "takes ownership" comments and manual "delete" invocations in favor > > of simply using std::unique_ptr. > > > > The problem is that the patch makes use of std::make_unique, but > > that > > was added in C++14. > > > > I've heard that it's reasonably easy to reimplement > > std::make_unique, > > but I'm not sure that my C++11 skills are up to it. > > You know we have an implementation of std::make_unique in GCC, with a > GCC-compatible licence that you can look at, right? :-) > > But it's not really necessary. There are only two reasons to prefer > make_unique over just allocating an object with new and constructing > a > unique_ptr from it: > > 1) avoid a "naked" new in your code (some coding styles like this, > but > it's not really important as long as the 'delete' is managed > automatically by unique_ptr). > > 2) exception-safety when allocating multiple objects as args to a > function, see https://herbsutter.com/gotw/_102/ for details. > Irrelevant for GCC, because we build without exceptions. [moving from gcc to gcc-patches mailing list] Also, I *think* it's a lot less typing, since I can write just: std::make_unique<name_of_type_which_could_be_long> (args) rather than std::unique_ptr<name_of_type_which_could_be_long> (new name_of_type_which_could_be_long (args)); > > > > > Is there: > > (a) an easy way to implement a std::make_unique replacement > > (e.g. in system.h? what to call it?), or > > If you don't care about using it to create unique_ptr<T[]> arrays, > it's trivial: > > template<typename T, typename... Args> > inline typename std::enable_if<!std::is_array<T>::value, > std::unique_ptr<T>>::type > make_unique(Args&&... args) > { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); > } > > To add the overload that works for arrays is a little trickier. Thanks! I tried adding it to gcc/system.h, but anything that uses it needs to have std::unique_ptr declared, which meant forcibly including <memory> from gcc/system.h So instead, here's a patch that adds a new gcc/make-unique.h header, containing just the template decl above (in the root namespace, rather than std::, which saves a bit more typing). I've successfully bootstrapped®ression-tested a version of my earlier analyzer patch that uses this patch (see patch 2 of the kit, which has lots of usage examples). OK for trunk? Dave This patch adds gcc/make-unique.h, containing a minimal C++11 implementation of make_unique (std::make_unique is C++14). gcc/ChangeLog: * make-unique.h: New file. Signed-off-by: David Malcolm <dmalcolm@redhat.com> --- gcc/make-unique.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 gcc/make-unique.h
Comments
On Tue, 12 Jul 2022, 01:25 David Malcolm, <dmalcolm@redhat.com> wrote: > On Fri, 2022-07-08 at 22:16 +0100, Jonathan Wakely wrote: > > On Fri, 8 Jul 2022 at 21:47, David Malcolm via Gcc <gcc@gcc.gnu.org> > > wrote: > > > > > > std::unique_ptr is C++11, and I'd like to use it in the > > > gcc/analyzer > > > subdirectory, at least. The following patch eliminates a bunch of > > > "takes ownership" comments and manual "delete" invocations in favor > > > of simply using std::unique_ptr. > > > > > > The problem is that the patch makes use of std::make_unique, but > > > that > > > was added in C++14. > > > > > > I've heard that it's reasonably easy to reimplement > > > std::make_unique, > > > but I'm not sure that my C++11 skills are up to it. > > > > You know we have an implementation of std::make_unique in GCC, with a > > GCC-compatible licence that you can look at, right? :-) > > > > But it's not really necessary. There are only two reasons to prefer > > make_unique over just allocating an object with new and constructing > > a > > unique_ptr from it: > > > > 1) avoid a "naked" new in your code (some coding styles like this, > > but > > it's not really important as long as the 'delete' is managed > > automatically by unique_ptr). > > > > 2) exception-safety when allocating multiple objects as args to a > > function, see https://herbsutter.com/gotw/_102/ for details. > > Irrelevant for GCC, because we build without exceptions. > > [moving from gcc to gcc-patches mailing list] > > Also, I *think* it's a lot less typing, since I can write just: > > std::make_unique<name_of_type_which_could_be_long> (args) > > rather than > > std::unique_ptr<name_of_type_which_could_be_long> (new > name_of_type_which_could_be_long (args)); > > > > > > > > > > Is there: > > > (a) an easy way to implement a std::make_unique replacement > > > (e.g. in system.h? what to call it?), or > > > > If you don't care about using it to create unique_ptr<T[]> arrays, > > it's trivial: > > > > template<typename T, typename... Args> > > inline typename std::enable_if<!std::is_array<T>::value, > > std::unique_ptr<T>>::type > > make_unique(Args&&... args) > > { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); > > } > > > > To add the overload that works for arrays is a little trickier. > > Thanks! > > I tried adding it to gcc/system.h, but anything that uses it needs to > have std::unique_ptr declared, which meant forcibly including <memory> > from gcc/system.h > > So instead, here's a patch that adds a new gcc/make-unique.h header, > containing just the template decl above (in the root namespace, rather > than std::, which saves a bit more typing). > Adding things to std isn't allowed anyway, so that's correct. > I've successfully bootstrapped®ression-tested a version of my earlier > analyzer patch that uses this patch (see patch 2 of the kit, which has > lots of usage examples). > > OK for trunk? > > Dave > > > > This patch adds gcc/make-unique.h, containing a minimal C++11 > implementation of make_unique (std::make_unique is C++14). > > gcc/ChangeLog: > * make-unique.h: New file. > > Signed-off-by: David Malcolm <dmalcolm@redhat.com> > --- > gcc/make-unique.h | 41 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 41 insertions(+) > create mode 100644 gcc/make-unique.h > > diff --git a/gcc/make-unique.h b/gcc/make-unique.h > new file mode 100644 > index 00000000000..c99c5328545 > --- /dev/null > +++ b/gcc/make-unique.h > @@ -0,0 +1,41 @@ > +/* Minimal implementation of make_unique for C++11 compatibility. > + Copyright (C) 2022 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#ifndef GCC_MAKE_UNIQUE > +#define GCC_MAKE_UNIQUE > + > +/* This header uses std::unique_ptr, but <memory> can't be directly > + included due to issues with macros. Hence it must be included from > + system.h by defining INCLUDE_MEMORY in any source file using it. */ > + > +#ifndef INCLUDE_MEMORY > +# error "You must define INCLUDE_MEMORY before including system.h to use > make-unique.h" > +#endif > You also need <type_traits> for the enable_if and is_array traits. With libstdc++ that gets included by <memory> but that's guaranteed for other library implementations. I don't know if that had the same kind of issues as other system headers or if it can just be included here. + > +/* Minimal implementation of make_unique for C++11 compatibility > + (std::make_unique is C++14). */ > + > +template<typename T, typename... Args> > +inline typename std::enable_if<!std::is_array<T>::value, > std::unique_ptr<T>>::type > +make_unique(Args&&... args) > +{ > + return std::unique_ptr<T> (new T (std::forward<Args> (args)...)); > +} > + > +#endif /* ! GCC_MAKE_UNIQUE */ > -- > 2.26.3 > >
On Tue, 12 Jul 2022 at 07:48, Jonathan Wakely wrote:
> You also need <type_traits> for the enable_if and is_array traits. With libstdc++ that gets included by <memory> but that's guaranteed for other library implementations.
Sorry, I was replying from my phone and missed a word. That's **not**
guaranteed for other library implementations.
(It's not formally guaranteed for libstdc++ either, but in practice
nearly every libstdc++ header includes <type_traits> because nearly
every header needs part of it, and that's unlikely to change).
On 2022-07-12 1:25 a.m., David Malcolm via Gcc-patches wrote: > I tried adding it to gcc/system.h, but anything that uses it needs to > have std::unique_ptr declared, which meant forcibly including <memory> > from gcc/system.h Did you consider making gcc/system.h include gcc/make-unique.h itself if INCLUDE_MEMORY is defined? Something like: #ifdef INCLUDE_MEMORY # include <memory> + #include "make-unique.h" #endif This is because std::make_unique is defined in <memory> in C++14. This would mean fewer changes once GCC requires C++14 (or later) and this new header is eliminated. > (in the root namespace, rather than std::, which saves a bit more typing). It's less typing now, but it will be more churn once GCC requires C++14 (or later), at which point you'll naturally want to get rid of the custom make_unique. More churn since make_unique -> std::make_unique may require re-indentation of arguments, etc. For that reason, I would suggest instead to put the function (and any other straight standard library backport) in a 3-letter namespace already, like, gcc::make_unique or gnu::make_unique. That way, when the time comes that GCC requires C++14, the patch to replace gcc::make_unique won't have to worry about reindenting code, it'll just replace gcc -> std.
On Tue, 12 Jul 2022 at 14:24, Pedro Alves wrote: > > On 2022-07-12 1:25 a.m., David Malcolm via Gcc-patches wrote: > > > I tried adding it to gcc/system.h, but anything that uses it needs to > > have std::unique_ptr declared, which meant forcibly including <memory> > > from gcc/system.h > > Did you consider making gcc/system.h include gcc/make-unique.h itself > if INCLUDE_MEMORY is defined? Something like: > > #ifdef INCLUDE_MEMORY > # include <memory> > + #include "make-unique.h" > #endif > > This is because std::make_unique is defined in <memory> in C++14. This would > mean fewer changes once GCC requires C++14 (or later) and this new header is eliminated. That's a good idea. > > (in the root namespace, rather than std::, which saves a bit more typing). > > It's less typing now, but it will be more churn once GCC requires C++14 (or later), at > which point you'll naturally want to get rid of the custom make_unique. More churn > since make_unique -> std::make_unique may require re-indentation of arguments, etc. > For that reason, I would suggest instead to put the function (and any other straight > standard library backport) in a 3-letter namespace already, like, gcc::make_unique > or gnu::make_unique. That way, when the time comes that GCC requires C++14, > the patch to replace gcc::make_unique won't have to worry about reindenting code, > it'll just replace gcc -> std. Or (when the time comes) don't change gcc->std and do: namespace gcc { using std::make_unique; } or just leave it in the global namespace as in your current patch, and at a later date add a using-declaration to the global namespace: using std::make_unique;
On 2022-07-12 2:45 p.m., Jonathan Wakely wrote: > On Tue, 12 Jul 2022 at 14:24, Pedro Alves wrote: >> >> On 2022-07-12 1:25 a.m., David Malcolm via Gcc-patches wrote: >> >>> I tried adding it to gcc/system.h, but anything that uses it needs to >>> have std::unique_ptr declared, which meant forcibly including <memory> >>> from gcc/system.h >> >> Did you consider making gcc/system.h include gcc/make-unique.h itself >> if INCLUDE_MEMORY is defined? Something like: >> >> #ifdef INCLUDE_MEMORY >> # include <memory> >> + #include "make-unique.h" >> #endif >> >> This is because std::make_unique is defined in <memory> in C++14. This would >> mean fewer changes once GCC requires C++14 (or later) and this new header is eliminated. > > That's a good idea. > >>> (in the root namespace, rather than std::, which saves a bit more typing). >> >> It's less typing now, but it will be more churn once GCC requires C++14 (or later), at >> which point you'll naturally want to get rid of the custom make_unique. More churn >> since make_unique -> std::make_unique may require re-indentation of arguments, etc. >> For that reason, I would suggest instead to put the function (and any other straight >> standard library backport) in a 3-letter namespace already, like, gcc::make_unique >> or gnu::make_unique. That way, when the time comes that GCC requires C++14, >> the patch to replace gcc::make_unique won't have to worry about reindenting code, >> it'll just replace gcc -> std. > > Or (when the time comes) don't change gcc->std and do: > > namespace gcc { > using std::make_unique; > } It will seem like a pointless indirection then, IMO. > > or just leave it in the global namespace as in your current patch, and > at a later date add a using-declaration to the global namespace: > > using std::make_unique; > That's not very idiomatic, though. Let me turn this into a reverse question: If GCC required C++14 today, would you be doing the above, either importing make_unique to the global namespace, or into namespace gcc? I think it's safe to say that, no, nobody would be doing that. So once GCC requires C++14, why would you want to preserve once-backported symbols in a namespace other than std, when you no longer have a reason to? It will just be another unnecessary thing that newcomers at that future time will have to learn.
On Tue, 12 Jul 2022 at 15:06, Pedro Alves <pedro@palves.net> wrote: > > On 2022-07-12 2:45 p.m., Jonathan Wakely wrote: > > On Tue, 12 Jul 2022 at 14:24, Pedro Alves wrote: > >> > >> On 2022-07-12 1:25 a.m., David Malcolm via Gcc-patches wrote: > >> > >>> I tried adding it to gcc/system.h, but anything that uses it needs to > >>> have std::unique_ptr declared, which meant forcibly including <memory> > >>> from gcc/system.h > >> > >> Did you consider making gcc/system.h include gcc/make-unique.h itself > >> if INCLUDE_MEMORY is defined? Something like: > >> > >> #ifdef INCLUDE_MEMORY > >> # include <memory> > >> + #include "make-unique.h" > >> #endif > >> > >> This is because std::make_unique is defined in <memory> in C++14. This would > >> mean fewer changes once GCC requires C++14 (or later) and this new header is eliminated. > > > > That's a good idea. > > > >>> (in the root namespace, rather than std::, which saves a bit more typing). > >> > >> It's less typing now, but it will be more churn once GCC requires C++14 (or later), at > >> which point you'll naturally want to get rid of the custom make_unique. More churn > >> since make_unique -> std::make_unique may require re-indentation of arguments, etc. > >> For that reason, I would suggest instead to put the function (and any other straight > >> standard library backport) in a 3-letter namespace already, like, gcc::make_unique > >> or gnu::make_unique. That way, when the time comes that GCC requires C++14, > >> the patch to replace gcc::make_unique won't have to worry about reindenting code, > >> it'll just replace gcc -> std. > > > > Or (when the time comes) don't change gcc->std and do: > > > > namespace gcc { > > using std::make_unique; > > } > > It will seem like a pointless indirection then, IMO. > > > > > or just leave it in the global namespace as in your current patch, and > > at a later date add a using-declaration to the global namespace: > > > > using std::make_unique; > > > > That's not very idiomatic, though. Let me turn this into a reverse question: > > If GCC required C++14 today, would you be doing the above, either importing make_unique > to the global namespace, or into namespace gcc? I think it's safe to say that, no, > nobody would be doing that. Erm, I might well do exactly that, for either case. I don't see a problem with 'using std::make_unique;' into the global namespace in GCC code. It's not a library header being included by arbitrary code, it's a single application that isn't going to have conflicts for some other ::make_unique defined in GCC (because the ::make_unique that is being proposed today would be removed once C++14's std::make_unique can be used). > So once GCC requires C++14, why would you want to preserve > once-backported symbols in a namespace other than std, when you no longer have a reason to? > It will just be another unnecessary thing that newcomers at that future time will have > to learn. I also don't see a problem with importing std::make_unique into namespace gcc for local use alongside other things in namespace gcc. I do consider that idiomatic. It says "the make_unique for gcc code is std::make_unique". It means you only need a 'using namespace gcc;' at the top of a source file and you get access to everything in namespace gcc, even if it is something like std::make_unique that was originally defined in a different namespace.
On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: >> So once GCC requires C++14, why would you want to preserve >> once-backported symbols in a namespace other than std, when you no longer have a reason to? >> It will just be another unnecessary thing that newcomers at that future time will have >> to learn. > > I also don't see a problem with importing std::make_unique into > namespace gcc for local use alongside other things in namespace gcc. I > do consider that idiomatic. It says "the make_unique for gcc code is > std::make_unique". It means you only need a 'using namespace gcc;' at > the top of a source file and you get access to everything in namespace > gcc, even if it is something like std::make_unique that was originally > defined in a different namespace. > If that's the approach, then GCC should import std::unique_ptr, std::move, std::foo, std::bar into the gcc namespace too, no? Are you really going to propose that?
On Tue, 12 Jul 2022, 17:40 Pedro Alves, <pedro@palves.net> wrote: > On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: > > >> So once GCC requires C++14, why would you want to preserve > >> once-backported symbols in a namespace other than std, when you no > longer have a reason to? > >> It will just be another unnecessary thing that newcomers at that future > time will have > >> to learn. > > > > I also don't see a problem with importing std::make_unique into > > namespace gcc for local use alongside other things in namespace gcc. I > > do consider that idiomatic. It says "the make_unique for gcc code is > > std::make_unique". It means you only need a 'using namespace gcc;' at > > the top of a source file and you get access to everything in namespace > > gcc, even if it is something like std::make_unique that was originally > > defined in a different namespace. > > > > If that's the approach, then GCC should import std::unique_ptr, std::move, > std::foo, std::bar into the gcc namespace too, no? Are you really going > to propose that? > No, I don't follow the logic of "if you do it for one thing you must do it for everything". That's a straw man. But I don't really mind how this gets done. Your suggestion is fine. >
On 2022-07-12 7:22 p.m., Jonathan Wakely wrote: > > > On Tue, 12 Jul 2022, 17:40 Pedro Alves, <pedro@palves.net <mailto:pedro@palves.net>> wrote: > > On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: > > >> So once GCC requires C++14, why would you want to preserve > >> once-backported symbols in a namespace other than std, when you no longer have a reason to? > >> It will just be another unnecessary thing that newcomers at that future time will have > >> to learn. > > > > I also don't see a problem with importing std::make_unique into > > namespace gcc for local use alongside other things in namespace gcc. I > > do consider that idiomatic. It says "the make_unique for gcc code is > > std::make_unique". It means you only need a 'using namespace gcc;' at > > the top of a source file and you get access to everything in namespace > > gcc, even if it is something like std::make_unique that was originally > > defined in a different namespace. > > > > If that's the approach, then GCC should import std::unique_ptr, std::move, > std::foo, std::bar into the gcc namespace too, no? Are you really going > to propose that? > > > No, I don't follow the logic of "if you do it for one thing you must do it for everything". That's a straw man. But I don't really mind how this gets done. Your suggestion is fine. > It isn't a strawman, Jon. Maybe there's some miscommunication. The conversion started (and part of it is still quoted above), by thinking about what we'd do once we get to C++14, and my suggestion to optimize for that. When we get to the point when we require C++14, make_unique is no longer different from any other symbol in the std namespace, and there will be no reason to treat it differently anymore. Like, if someone at that point proposes to remove the global make_unique or gcc::make_unique, and replace all references with std::make_unique, there will be no real ground to object to that, why wouldn't you want it? This is very much like when you removed "gnu::unique_ptr" (not going to miss it) a few months back -- you replaced it by "std::unique_ptr"; gnu::unique_ptr wasn't kept just because of history. Cheers, Pedro Alves
On Tue, 2022-07-12 at 17:40 +0100, Pedro Alves wrote: > On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: > > > > So once GCC requires C++14, why would you want to preserve I look forward to the happy day when we can use C++14 in GCC's implementation, but I don't see it happening anytime soon. GCC's needs may differ from those of GDB's. I'm not very familiar with GDB's insides, but, for example, GCC has its own garbage-collector which complicates everything to do with memory managements. Right now I have comments expressing ownership of some pointers, and e.g. "takes ownership of ...". It would be wonderful to take some baby steps into using C++11 to express the ownership directly in code. > > > once-backported symbols in a namespace other than std, when you > > > no longer have a reason to? > > > It will just be another unnecessary thing that newcomers at that > > > future time will have > > > to learn. > > > > I also don't see a problem with importing std::make_unique into > > namespace gcc for local use alongside other things in namespace > > gcc. I > > do consider that idiomatic. It says "the make_unique for gcc code > > is > > std::make_unique". It means you only need a 'using namespace gcc;' > > at > > the top of a source file and you get access to everything in > > namespace > > gcc, even if it is something like std::make_unique that was > > originally > > defined in a different namespace. Jonathan's idea sounds good to me. > > > > If that's the approach, then GCC should import std::unique_ptr, > std::move, > std::foo, std::bar into the gcc namespace too, no? Are you really > going > to propose that? Pedro, it feels to me like you're constructing a strawman here. Neither me nor Jonathan are proposing that. I just want to be able to comfortably use std::unique_ptr in GCC in the places for which it makes sense, and being able to use "make_unique" is a part of that. Hope this is constructive Dave
On 2022-07-12 7:36 p.m., Pedro Alves wrote: > On 2022-07-12 7:22 p.m., Jonathan Wakely wrote: >> >> >> On Tue, 12 Jul 2022, 17:40 Pedro Alves, <pedro@palves.net <mailto:pedro@palves.net>> wrote: >> >> On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: >> >> >> So once GCC requires C++14, why would you want to preserve >> >> once-backported symbols in a namespace other than std, when you no longer have a reason to? >> >> It will just be another unnecessary thing that newcomers at that future time will have >> >> to learn. >> > >> > I also don't see a problem with importing std::make_unique into >> > namespace gcc for local use alongside other things in namespace gcc. I >> > do consider that idiomatic. It says "the make_unique for gcc code is >> > std::make_unique". It means you only need a 'using namespace gcc;' at >> > the top of a source file and you get access to everything in namespace >> > gcc, even if it is something like std::make_unique that was originally >> > defined in a different namespace. >> > >> >> If that's the approach, then GCC should import std::unique_ptr, std::move, >> std::foo, std::bar into the gcc namespace too, no? Are you really going >> to propose that? >> >> >> No, I don't follow the logic of "if you do it for one thing you must do it for everything". That's a straw man. But I don't really mind how this gets done. Your suggestion is fine. >> > > It isn't a strawman, Jon. Maybe there's some miscommunication. The conversion started (and part of it is > still quoted above), by thinking about what we'd do once we get to C++14, and my suggestion to optimize > for that. When we get to the point when we require C++14, make_unique is no longer different from any other > symbol in the std namespace, and there will be no reason to treat it differently anymore. Like, if someone at > that point proposes to remove the global make_unique or gcc::make_unique, and replace all references with > std::make_unique, there will be no real ground to object to that, why wouldn't you want it? This is very > much like when you removed "gnu::unique_ptr" (not going to miss it) a few months back -- you replaced > it by "std::unique_ptr"; gnu::unique_ptr wasn't kept just because of history. Sorry to reply to myself -- but I'm not sure it is clear what I meant above in the last sentence, so let me try again: 'the "gnu::unique_ptr" wasn't rewritten as an import of std::unique_ptr into the gnu namespace just because of history.'
On 2022-07-12 7:36 p.m., David Malcolm wrote: > On Tue, 2022-07-12 at 17:40 +0100, Pedro Alves wrote: >>> >> >> If that's the approach, then GCC should import std::unique_ptr, >> std::move, >> std::foo, std::bar into the gcc namespace too, no? Are you really >> going >> to propose that? > > Pedro, it feels to me like you're constructing a strawman here. > Neither me nor Jonathan are proposing that. > See my other reply. I am actually appalled at how the conversion seems to have derailed. > I just want to be able to comfortably use std::unique_ptr in GCC in the > places for which it makes sense, and being able to use "make_unique" is > a part of that. My suggestion was simple: wrap your make_unique in namespace gcc, so that later on when we get to C++14, yanking it out causes as little churn as possible, with just a 3 letters for 3 letters replacement. I never thought this would be objectionable. If you don't want to do that, that's fine, the churn will happen in the future, but it's no big deal. You'll get to live with shorter make_unique for a few years (my bet is not forever). > > Hope this is constructive > Dave > >
On Tue, 12 Jul 2022, 19:36 Pedro Alves, <pedro@palves.net> wrote: > On 2022-07-12 7:22 p.m., Jonathan Wakely wrote: > > > > > > On Tue, 12 Jul 2022, 17:40 Pedro Alves, <pedro@palves.net <mailto: > pedro@palves.net>> wrote: > > > > On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: > > > > >> So once GCC requires C++14, why would you want to preserve > > >> once-backported symbols in a namespace other than std, when you > no longer have a reason to? > > >> It will just be another unnecessary thing that newcomers at that > future time will have > > >> to learn. > > > > > > I also don't see a problem with importing std::make_unique into > > > namespace gcc for local use alongside other things in namespace > gcc. I > > > do consider that idiomatic. It says "the make_unique for gcc code > is > > > std::make_unique". It means you only need a 'using namespace gcc;' > at > > > the top of a source file and you get access to everything in > namespace > > > gcc, even if it is something like std::make_unique that was > originally > > > defined in a different namespace. > > > > > > > If that's the approach, then GCC should import std::unique_ptr, > std::move, > > std::foo, std::bar into the gcc namespace too, no? Are you really > going > > to propose that? > > > > > > No, I don't follow the logic of "if you do it for one thing you must do > it for everything". That's a straw man. But I don't really mind how this > gets done. Your suggestion is fine. > > > > It isn't a strawman, Jon. Maybe there's some miscommunication. The > conversion started (and part of it is > still quoted above), by thinking about what we'd do once we get to C++14, > and my suggestion to optimize > for that. Yeah, and I don't think optimizing for indentation is the right trade off. Putting something in a namespace with a three-letter name just so you don't have to re-indent some statements in a few years seems odd. I see no technical difficulty replacing a custom make_unique (in any namespace) with std::make_unique at a later date. If a namespace made sense to avoid name clashes, or to enable finding functions by ADL, or other technical reasons, I'd be all for it. But no such rationale was given, and using a namespace for indentation just seems odd to me. But I really don't care. Putting it in the global namespace or a 'gcc' namespace or anything else appropriate to GCC is fine. I'll leave this thread now. I don't think this is very constructive and I'm sorry for objecting to the suggestion. When we get to the point when we require C++14, make_unique is no longer > different from any other > symbol in the std namespace, and there will be no reason to treat it > differently anymore. Like, if someone at > that point proposes to remove the global make_unique or gcc::make_unique, > and replace all references with > std::make_unique, there will be no real ground to object to that, why > wouldn't you want it? This is very > much like when you removed "gnu::unique_ptr" (not going to miss it) a few > months back -- you replaced > it by "std::unique_ptr"; gnu::unique_ptr wasn't kept just because of > history. > > Cheers, > Pedro Alves >
On 2022-07-12 7:50 p.m., Jonathan Wakely wrote: > Yeah, and I don't think optimizing for indentation is the right trade off. Putting something in a namespace with a three-letter name just so you don't have to re-indent some statements in a few years seems odd. > > I see no technical difficulty replacing a custom make_unique (in any namespace) with std::make_unique at a later date. > > If a namespace made sense to avoid name clashes, or to enable finding functions by ADL, or other technical reasons, I'd be all for it. But no such rationale was given, and using a namespace for indentation just seems odd to me. > > But I really don't care. Putting it in the global namespace or a 'gcc' namespace or anything else appropriate to GCC is fine. I'll leave this thread now. I don't think this is very constructive and I'm sorry for objecting to the suggestion. That's fair. Cheers! Hope we'll be able to laugh about it in Prague!
On Tue, 12 Jul 2022 at 19:41, Pedro Alves <pedro@palves.net> wrote: > > On 2022-07-12 7:36 p.m., Pedro Alves wrote: > > On 2022-07-12 7:22 p.m., Jonathan Wakely wrote: > >> > >> > >> On Tue, 12 Jul 2022, 17:40 Pedro Alves, <pedro@palves.net <mailto:pedro@palves.net>> wrote: > >> > >> On 2022-07-12 4:14 p.m., Jonathan Wakely wrote: > >> > >> >> So once GCC requires C++14, why would you want to preserve > >> >> once-backported symbols in a namespace other than std, when you no longer have a reason to? > >> >> It will just be another unnecessary thing that newcomers at that future time will have > >> >> to learn. > >> > > >> > I also don't see a problem with importing std::make_unique into > >> > namespace gcc for local use alongside other things in namespace gcc. I > >> > do consider that idiomatic. It says "the make_unique for gcc code is > >> > std::make_unique". It means you only need a 'using namespace gcc;' at > >> > the top of a source file and you get access to everything in namespace > >> > gcc, even if it is something like std::make_unique that was originally > >> > defined in a different namespace. > >> > > >> > >> If that's the approach, then GCC should import std::unique_ptr, std::move, > >> std::foo, std::bar into the gcc namespace too, no? Are you really going > >> to propose that? > >> > >> > >> No, I don't follow the logic of "if you do it for one thing you must do it for everything". That's a straw man. But I don't really mind how this gets done. Your suggestion is fine. > >> > > > > It isn't a strawman, Jon. Maybe there's some miscommunication. The conversion started (and part of it is > > still quoted above), by thinking about what we'd do once we get to C++14, and my suggestion to optimize > > for that. When we get to the point when we require C++14, make_unique is no longer different from any other > > symbol in the std namespace, and there will be no reason to treat it differently anymore. Like, if someone at > > that point proposes to remove the global make_unique or gcc::make_unique, and replace all references with > > std::make_unique, there will be no real ground to object to that, why wouldn't you want it? This is very > > much like when you removed "gnu::unique_ptr" (not going to miss it) a few months back -- you replaced > > it by "std::unique_ptr"; gnu::unique_ptr wasn't kept just because of history. > > Sorry to reply to myself -- but I'm not sure it is clear what I meant above in the last sentence, so let > me try again: 'the "gnu::unique_ptr" wasn't rewritten as an import of std::unique_ptr into the gnu namespace > just because of history.' [OFFLIST] I considered doing exactly that. But because namespace gnu wasn't used anywhere else in GCC it didn't make sense. If it had been put in namespace gcc, which is still used elsewhere in the GCC codebase, I might have decided differently. But keeping namespace 'gnu' with no content except 'using std::unique_ptr;' would have been pointless. It wouldn't have made it easier for other things in namespace gnu to refer to it, because there were no other things. It wouldn't have allowed 'using namespace gnu;' to make various useful utilities available with a single using-directive, because that would only make one thing available, and 'using std::unique_ptr;' does that just as effectively.
On Tue, 12 Jul 2022 at 19:58, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> [OFFLIST]
Oops, sorry, reply-all fail. I meant to spare everybody any further
musing on this topic.
Really leaving the thread now!
diff --git a/gcc/make-unique.h b/gcc/make-unique.h new file mode 100644 index 00000000000..c99c5328545 --- /dev/null +++ b/gcc/make-unique.h @@ -0,0 +1,41 @@ +/* Minimal implementation of make_unique for C++11 compatibility. + Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_MAKE_UNIQUE +#define GCC_MAKE_UNIQUE + +/* This header uses std::unique_ptr, but <memory> can't be directly + included due to issues with macros. Hence it must be included from + system.h by defining INCLUDE_MEMORY in any source file using it. */ + +#ifndef INCLUDE_MEMORY +# error "You must define INCLUDE_MEMORY before including system.h to use make-unique.h" +#endif + +/* Minimal implementation of make_unique for C++11 compatibility + (std::make_unique is C++14). */ + +template<typename T, typename... Args> +inline typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type +make_unique(Args&&... args) +{ + return std::unique_ptr<T> (new T (std::forward<Args> (args)...)); +} + +#endif /* ! GCC_MAKE_UNIQUE */