currently, in <tr1/type_traits>, code exists like: template<typename _Tp> struct has_trivial_destructor : public integral_constant<bool, is_pod<_Tp>::value> { }; It would be nice to have compiler support to detect non-pod types that have a trivial destructor. (this would provide support for certain optimizations)
Wouldn't it be better to ask the standards committee to add support than asking GCC to add an extension? Also what kind of optimizations can you do with a trival destructor?
When I saw "tr1" in the path, I assumed this referred to the technical report of the standards committee. I recognize a technical report is not a standard, thus I am simply inquiring if there is interest in adding this feature. I see code in <bits/stl_construct.h>, function _Destroy, that allows for optimizations when this support is available. A second example, I am myself writing a container class that allows allocation+construction of chunks of variable size at a time (aiming for lower computational cost). When erasing a single element from that container, its destruction would have to be done immediately, while its memory chunk would remain allocated. Some (expensive) bookkeeping has to be done to later facilitate correct destruction and deallocation of remaining elements when the container itself is destroyed. If has_trivial_destructor would be true_type, all this bookkeeping could be omitted, and on destruction of the container just the deallocation of all the used memory would be sufficient. I am no expert on the implementation details of existing containers, but I guess similar optimizations throughout libstdc++ are possible.
(In reply to comment #2) > When I saw "tr1" in the path, I assumed this referred to the technical report > of the standards committee. I recognize a technical report is not a standard, > thus I am simply inquiring if there is interest in adding this feature. Yes TR1 refers to the technical report which is really just the library part. The interest should really go to the committe than one implementation. Now GCC can add this as an extensions and that can help the discussion/decision to add it to the standard. But GCC's view of extensions have changed over the years and right now it is that extensions are bad and should be avoided. I am not saying this is not useful after your description of how to speed up some containers. Now the book keeping is not that expensive as it is just an extra bool for each slot and you can hide most of the book keeping in a secondary class.
> Yes TR1 refers to the technical report which is really just the library part. For the library to provide this functionality, it has to exist in the compiler, as a whole, or by a clever combination of language constructs. Currently, it doesn't seem to me that this proposal could be implemented using gcc. If it is the desire of the gcc developers to adhere to the iso standard and no more, I don't intend to argue on that, as I currently don't have the means (free time nor adequate gcc code knowledge) to contribute code.
Really, what Stefaan is saying is trivially correct and totally sensible. The only doubt I have is which *specific* shape the compiler support must take. In fact, I find TR1, 4.9 too vague about that. Then the point would be (I think Andrew will agree): let's suppose some sort of ""reflection"" becomes part of the next C++ standard, then the whole core C++ + type_traits becomes absolutely natural and neat. I think many people would like standardization in this area, but if C++0x will not include it (a huge number of new features is already scheduled!), we have to accept ""extensions"" if we want performance and QoI in the library. This is already happening today in many areas, consider, e.g., thread safe locales, math builtins, lots of examples, really.
Subject: Re: support for type traits is not available "pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | The interest should really go to the committe than one | implementation. Now GCC can add this as an extensions and that can | help the discussion/decision to add it to the standard. I have no doubt many (all?) of of the tr1 traits will be part of C++0x. I think the PR is a valid request for enhancement, with priority higher than most requests for enhancements I've seen. -- Gaby
Confirmed.
Trying to make progress...
Subject: Bug 26099 Author: paolo Date: Fri Mar 30 20:45:57 2007 New Revision: 123366 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=123366 Log: gcc/ 2007-03-30 Paolo Carlini <pcarlini@suse.de> PR c++/26099 * c-common.h (enum rid): Add RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR, RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN, RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY, RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_VIRTUAL_DESTRUCTOR, RID_IS_ABSTRACT, RID_IS_BASE_OF, RID_IS_CONVERTIBLE_TO, RID_IS_CLASS, RID_IS_EMPTY, RID_IS_ENUM, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_UNION, as C++ extensions. * doc/extend.texi (Extensions to the C++ Language): Add Type Traits. gcc/cp/ 2007-03-30 Paolo Carlini <pcarlini@suse.de> PR c++/26099 * cp-tree.h (enum cp_trait_kind, struct tree_trait_expr, TRAIT_EXPR_TYPE1, TRAIT_EXPR_TYPE2, TRAIT_EXPR_KIND): Add. (enum cp_tree_node_structure_enum, union lang_tree_node): Update. (CLASS_TYPE_NON_UNION_P): Add. (struct lang_type_class): Add has_complex_dflt. (TYPE_HAS_COMPLEX_DFLT, TYPE_HAS_TRIVIAL_DFLT): Add. (locate_copy, locate_ctor, locate_dtor, finish_trait_expr): Declare. * cp-tree.def: Add TRAIT_EXPR. * cp-objcp-common.c (cp_tree_size): Add TRAIT_EXPR case. * lex.c (struct resword): Add __has_nothrow_assign, __has_nothrow_constructor, __has_nothrow_copy, __has_trivial_assign, __has_trivial_constructor, __has_trivial_copy, __has_trivial_destructor, __has_virtual_destructor, __is_abstract, __is_base_of, __is_class, __is_convertible_to, __is_empty, __is_enum, __is_pod, __is_polymorphic, __is_union. * parser.c (cp_parser_primary_expression): Deal with the new RIDs. (cp_parser_trait_expr): New. * semantics.c (finish_trait_expr, trait_expr_value classtype_has_nothrow_copy_or_assign_p): New. * method.c (locate_copy, locate_ctor, locate_dtor): Do not define as static. * decl.c (cp_tree_node_structure): Add TRAIT_EXPR. * class.c (check_bases, check_field_decl, check_bases_and_members): Deal with TYPE_HAS_COMPLEX_DFLT (t) too. * pt.c (uses_template_parms, tsubst_copy_and_build, value_dependent_expression_p, type_dependent_expression_p): Deal with TRAIT_EXPR. * tree.c (cp_walk_subtrees): Deal with TRAIT_EXPR. gcc/testsuite/ 2007-03-30 Paolo Carlini <pcarlini@suse.de> PR c++/26099 * g++.dg/ext/is_base_of.C: New. * g++.dg/ext/has_virtual_destructor.C: New. * g++.dg/ext/is_polymorphic.C: New. * g++.dg/ext/is_base_of_diagnostic.C: New. * g++.dg/ext/is_enum.C: New. * g++.dg/ext/has_nothrow_assign.C: New. * g++.dg/ext/has_nothrow_constructor.C: New. * g++.dg/ext/is_empty.C: New. * g++.dg/ext/has_trivial_copy.C: New. * g++.dg/ext/has_trivial_assign.C: New. * g++.dg/ext/is_abstract.C: New. * g++.dg/ext/is_pod.C: New. * g++.dg/ext/has_nothrow_copy.C: New. * g++.dg/ext/is_class.C: New. * g++.dg/ext/has_trivial_constructor.C: New. * g++.dg/ext/is_union.C: New. * g++.dg/ext/has_trivial_destructor.C: New. * g++.dg/tree-ssa/pr22444.C: Adjust, avoid __is_pod. * g++.dg/template/crash43.C: Likewise. libstdc++-v3/ 2007-03-30 Paolo Carlini <pcarlini@suse.de> PR c++/26099 * include/bits/cpp_type_traits.h (struct __is_pod, struct __is_empty): Remove. * include/bits/valarray_array.h: Adjust. * include/bits/allocator.h: Likewise. * include/bits/stl_tree.h: Likewise. Added: trunk/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C trunk/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C trunk/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C trunk/gcc/testsuite/g++.dg/ext/has_trivial_assign.C trunk/gcc/testsuite/g++.dg/ext/has_trivial_constructor.C trunk/gcc/testsuite/g++.dg/ext/has_trivial_copy.C trunk/gcc/testsuite/g++.dg/ext/has_trivial_destructor.C trunk/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C trunk/gcc/testsuite/g++.dg/ext/is_abstract.C trunk/gcc/testsuite/g++.dg/ext/is_base_of.C trunk/gcc/testsuite/g++.dg/ext/is_base_of_diagnostic.C trunk/gcc/testsuite/g++.dg/ext/is_class.C trunk/gcc/testsuite/g++.dg/ext/is_empty.C trunk/gcc/testsuite/g++.dg/ext/is_enum.C trunk/gcc/testsuite/g++.dg/ext/is_pod.C trunk/gcc/testsuite/g++.dg/ext/is_polymorphic.C trunk/gcc/testsuite/g++.dg/ext/is_union.C Modified: trunk/gcc/ChangeLog trunk/gcc/c-common.h trunk/gcc/cp/ChangeLog trunk/gcc/cp/class.c trunk/gcc/cp/cp-objcp-common.c trunk/gcc/cp/cp-tree.def trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/lex.c trunk/gcc/cp/method.c trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c trunk/gcc/cp/semantics.c trunk/gcc/cp/tree.c trunk/gcc/doc/extend.texi trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/template/crash43.C trunk/gcc/testsuite/g++.dg/tree-ssa/pr22444.C trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/allocator.h trunk/libstdc++-v3/include/bits/cpp_type_traits.h trunk/libstdc++-v3/include/bits/stl_tree.h trunk/libstdc++-v3/include/bits/valarray_array.h
Hi Paolo, three of the tests you added for this enhancement have execute failures on i686-unknown-linux-gnu and x86_64-unknown-linux-gnu on mainline when compiled with -fpic/-fPIC. Is there some valid reason they should not pass? These are the last pic-specific errors on mainline (that I haven't already patched) so I'd really like to zap them somehow. I imagine these failures are important since the audit trail talks a lot about using this feature in the std library which is compiled pic. Would you please take a look and let me know what you think needs to be done? Thanks. FAIL: g++.dg/ext/has_nothrow_assign.C execution test FAIL: g++.dg/ext/has_nothrow_constructor.C execution test FAIL: g++.dg/ext/has_nothrow_copy.C execution test http://gcc.gnu.org/ml/gcc-testresults/2008-01/msg01322.html http://gcc.gnu.org/ml/gcc-testresults/2008-01/msg01290.html
From the -fpic/-fPIC logfile: has_nothrow_assign.exe: [...]/has_nothrow_assign.C:139: int main(): Assertion `(__has_nothrow_assign(E) && f<E>() && My<E>().f() && My2<E>::trait && My3<E>().f())' failed. FAIL: g++.dg/ext/has_nothrow_assign.C execution test has_nothrow_constructor.exe: [...]/has_nothrow_constructor.C:100: int main(): Assertion `(__has_nothrow_constructor(E) && f<E>() && My<E>().f() && My2<E>::trait && My3<E>().f())' failed. FAIL: g++.dg/ext/has_nothrow_constructor.C execution test has_nothrow_copy.exe: [...]/has_nothrow_copy.C:129: int main(): Assertion `(__has_nothrow_copy(E) && f<E>() && My<E>().f() && My2<E>::trait && My3<E>().f())' failed. FAIL: g++.dg/ext/has_nothrow_copy.C execution test
Yes, I noticed. Frankly, I'm not really worried because of the nature of the tests: the checks can give different answers depending on whether the compiler is able or not to figure out that a given function cannot throw. For some reason (which I agree would be interesting to understand in better detail), -fpic/PIC makes makes more difficult for the compiler to assess that a function cannot really throw. I'm not sure about the best way to fix that: we could just zap those specific tests which have such "instability", or condition the result on -fpic/PIC via macros, or something better. I would probably be tempted to go the first route, for 4.3.0., at least.
If a function isn't marked nothrow and the function can be overridden by a shared library (that is, it doesn't bind locally), the compiler cannot derive such property from its body. (I didn't look at the tests, but usually marking the affected functions nothrow or making them bind locally works around this problem).
(In reply to comment #13) > If a function isn't marked nothrow and the function can be overridden by a > shared library (that is, it doesn't bind locally), the compiler cannot derive > such property from its body. Thanks for the details. > (I didn't look at the tests, but usually marking the affected functions > nothrow or making them bind locally works around this problem). Well, the functions in those specific tests aren't marked no throw on purpose (we do have other tests for the no throw variants), because I was exactly testing that in some specific cases the C++ front-end is able to figure out by itself that the function doesn't really throw. All in all I'm now thinking that it's good to have such tests, we should only conditionalize the result of the tests on -fpic/PIC, I suppose we do have a macro for that?!?
> All in all I'm now thinking that > it's good to have such tests, we should only conditionalize the result of the > tests on -fpic/PIC, I suppose we do have a macro for that?!? How about binding locally when pic? E.g.: #ifdef __PIC__ static #endif function_foo()
Created attachment 15030 [details] Draft idea for the -fpic/-fPIC fails
Hi Kaveh. One problem I can see is that we are dealing with special member functions, like constructors and assignment operators. Can you see anything wrong with the straightforward implementation of idea per the attached patchlet? If it looks ok to you, it would be matter of doing the same for the other 2 files...
(In reply to comment #17) > Hi Kaveh. One problem I can see is that we are dealing with special member > functions, like constructors and assignment operators Ah, I guess you can't make those static. > Can you see anything > wrong with the straightforward implementation of idea per the attached > patchlet? If it looks ok to you, it would be matter of doing the same for the > other 2 files... It looks like you reversed the checks for the problematic cases when you see __PIC__. I wonder whether this will work on darwin which still binds locally for pic code. http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00495.html The regtester might barf on this change, I don't have darwin to check. If it does, maybe instead you simply nuke the problematic cases when you see __PIC__.
(In reply to comment #18) > If it does, maybe instead you simply nuke the problematic cases when you see > __PIC__. Another option that might work is to add -fpie when we see __PIC__. That should work on darwin etc as well.
Hi Kaveh. I just checked darwin and indeed, we have an issue there, which, AFAICS, is not worked around with -fpie. I say, let's just skip the test when __PIC__ is defined, and be done with it.
Since you are already set for this extended kind of testing, can you run the new patch? Thanks a lot in advance!
Created attachment 15031 [details] New draft
(In reply to comment #20) > Hi Kaveh. I just checked darwin and indeed, we have an issue there, which, > AFAICS, is not worked around with -fpie. Hmm, did you mean darwin failed with (your patch + -fpie) or just with -fpie and the original tests? I meant for just using -fpie on darwin with no other changes. I have tested a patch that fixes the tests on x86-linux-gnu using -fpie. If it works on darwin, then great. Otherwise I'll go with your option.
Patch which works on i686-unknown-linux-gnu: 2008-01-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * g++.dg/ext/has_nothrow_assign.C: Add -fpie when __PIC__. * g++.dg/ext/has_nothrow_constructor.C: Likewise. * g++.dg/ext/has_nothrow_copy.C: Likewise. diff -rup orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C --- orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C 2007-12-31 19:13:13.000000000 +0100 +++ egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C 2008-01-27 21:17:32.000000000 +0100 @@ -1,4 +1,5 @@ // { dg-do "run" } +// { dg-options "-fpie" { target { ! nonpic } } } #include <cassert> struct A diff -rup orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_const ructor.C --- orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C 2007-12-31 19:13:14.000000000 +0100 +++ egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C 2008-01-27 21:17:48.000000000 +0100 @@ -1,4 +1,5 @@ // { dg-do "run" } +// { dg-options "-fpie" { target { ! nonpic } } } #include <cassert> struct A diff -rup orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C --- orig/egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C 2007-12-31 19:13:14.000000000 +0100 +++ egcc-SVN20080126/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C 2008-01-27 21:17:54.000000000 +0100 @@ -1,4 +1,5 @@ // { dg-do "run" } +// { dg-options "-fpie" { target { ! nonpic } } } #include <cassert> struct A
(In reply to comment #22) > Created an attachment (id=15031) [edit] > New draft I tried your latest draft and it fails for has_nothrow_assign.C because of a typo. The third #ifndef has no macro so I get: has_nothrow_assign.C:149: error: no macro name given in #ifndef directive When I fix that it works.
(In reply to comment #23) > I meant for just using -fpie on darwin with no other changes. The problem I see, on darwin, is that -fpie cannot be passed to the driver, because eventually, the linker rejects -pie. Is that a know issue, dealt with automatically by the testing infrastructure? In that case, your patch is great, otherwise, or if things are going to be tricky, I say let's just go with mine (sorry about the typo) and spare time for something else ;)
(In reply to comment #26) > (In reply to comment #23) > > I meant for just using -fpie on darwin with no other changes. > The problem I see, on darwin, is that -fpie cannot be passed to the driver, > because eventually, the linker rejects -pie. Is that a know issue, dealt with > automatically by the testing infrastructure? In that case, your patch is great, Hmm, there are a couple of other tests using -fpie on darwin: ./g++.dg/parse/attr-externally-visible-1.C:/* { dg-options "-O3 -fwhole-program -fpie" { target *-*-darwin* } } */ ./g++.dg/other/first-global.C:/* { dg-options "-fpie" { target *-*-darwin* } } */ ./gcc.dg/pie-link.c:/* { dg-options "-fpie" } */ On closer inspection, the first two are compile-only, so the linker isn't invoked. The latter is only run on darwin[912], which I assume means darwin9 or later (10, 11, 12, 20, 21, 22, ...). > otherwise, or if things are going to be tricky, I say let's just go with mine > (sorry about the typo) and spare time for something else ;) So I guess you're using an older version of darwin that doesn't know about pie. In that case I guess your patch (with the typo fixed) is the best option. Will you be installing it? Thanks, --Kaveh
(In reply to comment #27) > So I guess you're using an older version of darwin that doesn't know about pie. I'm testing on Darwin 8.11, that is the last Tiger, still pretty common... > In that case I guess your patch (with the typo fixed) is the best option. > > Will you be installing it? Sure. Many thanks for your help! Paolo.
The -fpic/-fPIC failures have been fixed long ago in gcc-4.3.x. Can we close this bug?
Nope, let's keep it open as a reminder that we are still missing __is_convertible_to and the newer ones, needed to implement N2984 (I'm implementing three as we are speaking)
__is_convertible_to isn't such a big issue anymore, thanks to Core/1170 (in C++11 SFINAE includes access control, still unimplemented in GCC, though). However, we now need front-end support for the is_trivially_* traits.
The __is_trivially_* bits are tracked by c++/63362.