[Bug c++/22556] New: extern array: compatible declaration at function scope refused
extern int foo[]; // OK int foo[]={1,2,3}; extern int foo[]; // OK void bar(){ extern int foo[]; // g++: ERROR -- SHOULD BE OK } g++ 3.4.0, 3.4.3, 4.0.0 (cygwin), g++ 3.4.2 (mingw): xxx.cpp: In function 'void bar()': xxx.cpp:6: error: type mismatch with previous external decl of 'int foo []' xxx.cpp:2: error: previous external decl of 'int foo [3]' g++ 3.3.1, 3.3.2 (cygwin) issue a slightly different error message This may be related to PRs 21342 and 21502. Vladimir Marko -- Summary: extern array: compatible declaration at function scope refused Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: SWElef at post dot sk CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22556
[Bug c++/20812] contextual overload resolution failure for a member name found in two base classes
--- Additional Comments From SWElef at post dot sk 2005-04-15 07:30 --- I was wrong. std:10.2/2 (member name lookup) says [snip] If the resulting set of declarations are not all from sub-objects of the same type, or the set has a nonstatic member and includes members from distinct sub-objects, there is an ambiguity and the program is ill-formed. [snip] So the deduction may not succeed. On the other hand, IIRC it is also not supposed to fail since the paragraph 14.8.2/2 that names all reasons for deduction failure does not contain anything about this specific case. The only reason that seems a little similar reads Attempting to use a type in the qualifier portion of a qualified name that names a type when that type does not contain the specified member, or if the specified member is not a type where a type is required. and in this case the named type _contains_ the specified member, it's just ambiguous. To expose the problem I wrote this new snippet: struct B1{ typedef int T; }; struct B2{ typedef int T; }; struct D : B1, B2 { }; template typename X typename X::T foo() { return X::T(); } int main(){ fooD(); } gcc reports error: no matching function for call to `foo()'. Comeau Online says error: D::T is ambiguous which is very different (and IIRC correct). May be this PR should be resolved as INVALID and another one should be written with this snippet and a more appropriate subject. Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20812
[Bug c++/20812] contextual overload resolution failure for a member name found in two base classes
--- Additional Comments From SWElef at post dot sk 2005-04-08 07:33 --- Well, if we speak about other compilers, MSVC++ Toolkit 2003 supports my view on the first snippet and emits an ICE on the second. And the behaviour of Comeau Online is pretty irrelevant as it fails deduction even for testB1(0). From my tests it seems that Comeau Online fails deduction whenever there is a non-trivial expression using a template argument in the template function signature and typename void_holderint B1::*,T::foo::type is already too complicated. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20812
[Bug c++/20812] New: contextual overload resolution failure for a member name found in two base classes
The problem is best demonstrated by a code snippet. The following snippet shows it as a wrong-code, but if we remove the first function template test we get a rejects-valid case: #include iostream #include ostream struct B1 { int foo; }; struct B2 { double foo; }; struct D: B1, B2 { }; template typename T void test(...){ std::cout the class does not have member foo with type 'int B1::*' std::endl; } template typename T,T t struct void_holder { typedef void type; }; template typename T typename void_holderint B1::*,T::foo::type test(T*){ std::cout the class has member foo with type 'int B1::*' std::endl; } int main(){ testD(0); } A specialization of the second function template test should be chosen because the ambiguity between B1::foo and B2::foo can be resolved based on the context, but a specialization of the first function template test is mistakenly chosen. (Should we call it overload even though I chose non-function members? Doesn't matter, it's the same with function members anyway.) There is also a closely connected accepts-invalid case where the ambiguity causes deduction failure instead of an error, but it's on the edge of core issue #339. In PR6424 it was decided to say sorry, unimplemented: call_expr cannot be mangled due to a defect in the C++ ABI for most of the cases covered by core issue #339, but not for all. And this is a failure in one of those that work: struct B1 { int foo; }; struct B2 { double foo; }; struct D: B1, B2 { }; template typename T void test(...){ } template int struct void_holder { typedef void type; }; template typename T typename void_holdersizeof(T::foo)::type test(T*); int main(){ testD(0); // should cause an error, not a deduction failure // for the second function template test } Regards, Vladimir Marko -- Summary: contextual overload resolution failure for a member name found in two base classes Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: SWElef at post dot sk CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20812
[Bug c++/20812] contextual overload resolution failure for a member name found in two base classes
--- Additional Comments From SWElef at post dot sk 2005-04-07 18:12 --- I forgot to write that I used gcc-3.4.2-mingw, gcc-3.4.3-cygwin and gcc-4.0.0-experimental-20050130 and the results were the same, i.e. buggy. Vladimir Marko -- What|Removed |Added Keywords||accepts-invalid, rejects- ||valid, wrong-code http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20812
[Bug c++/20172] New: member function template declaration not instantiated during the instantiation of the enclosing class template
gcc accepts the following ill-formed code (tested with gcc3.4.2 (mingw) and various cygwin versions (from 3.3.1 to 3.4.3 and an experimental snapshot 4.0.0-20050130) ): template typename T struct foo{ template T t static void bar() { } }; template typename T fooT tester(T) { return fooT(); } int main(){ tester(1.2); return 0; } std:14.7.1/1 says ... The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, static data members and _member_templates_; ... Thus, the implicit instantiation of struct foodouble causes the instantiation of declaration template double t void foodouble::bar(); which is ill-formed and should be diagnosed. Remark 1: The signature of bar is unimportant, it just has to be a function. If one declares a nested template T t struct S; gcc correctly complains when instantiating foodouble. Remark 2: Shorter testcase consists of a declaration of the template foo and an explicit instantiation of foodouble, but the wording for implicit instantiation is much cleaner in this case so I decided to use it. Regards, Vladimir Marko -- Summary: member function template declaration not instantiated during the instantiation of the enclosing class template Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: SWElef at post dot sk CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20172
[Bug c++/20172] member function template declaration not instantiated during the instantiation of the enclosing class template
-- What|Removed |Added Keywords||accepts-invalid http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20172
[Bug libstdc++/19422] assoc. containers: ctor taking range is O(n log n) even if the range is sorted
--- Additional Comments From SWElef at post dot sk 2005-01-14 08:24 --- I was a little in a hurry, so I'll add a comment on the test programm now. The reference time of std::list ctor taking range must be linear. Thus it makes sence to have a look at the quotient of the second and third collumn in the output. And that's where you can see the logarithmic behaviour. It is visible even for std::allocator but the pool allocator makes it shine. After giving it some thought I believe that calling the insert_unique/insert_equal function is wrong. I don't think that any hint (position) can help to make the running time linear in distance(first,last). A special function should be writen for this purpose. Why? Are you aware of the fact that insert with hint has amortized *constant* complexity if t is inserted after p? (Table 69) As stated in some thread on std.comp.c++ recently, amortized is allways with respect to something and that part is missing from the standard. The usual interpretation in this case is that if you take an assoc. container in a given state and take the average time of the insertion with hint at every position, it should be a constant (i.e. also independent of size()). It is far from guaranteed to be constant if you make a lot of insertions at the end. The position==end() is special-cased in the insert_unique/insert_equal function with hint and a member function _M_rightmost() is used. [When I tried to make an own version of map I decided not to have the information about the rightmost node and I was able to satisfy all complexity requirements anyway (except those deffective). This influenced my previously expressed opinion.] With the access to the rightmost node in constant time the insertions at the end could actualy be in amortized constant time (amortized wrt. consecutive insertions at the end). This is just a feeling and needs to be proved. Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19422
[Bug libstdc++/19422] assoc. containers: ctor taking range is O(n log n) even if the range is sorted
--- Additional Comments From SWElef at post dot sk 2005-01-14 13:33 --- It took me quite a long time to realise that the best performance tests are those where we count the elementary operations. The best way to expose the O(n log n) complexity in non-fixed case is to supply the container with a comparator object that counts the invocations of operator() in some global variable. For an experimental proof that the fixed version is really linear one also needs to count the node manipulations by, say, replacing _Base_ptr with a smart pointer that acts as a plain pointer and counts every action (ctor, dtor, copy, dereference). Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19422
[Bug c++/19422] New: assoc. containers: ctor taking range is O(n log n) even if the range is sorted
The template constructor of associative containers with range [first,last) should have linear complexity if the range is sorted. libstdc++ fails to comply. This is quite evident when looking at the include file bits/stl_tree.h, more precisely the functions insert_unique and insert_equal taking ranges. To be sure I made some runtime tests. The complexity is really O(n log n), where n=distance(first,last). It is not evident with the default allocator, but one can see the trend. I also tested with a self-made single-threaded pool allocator and the results were very clear. I can submit the source if need be. Regards, Vladimir Marko -- Summary: assoc. containers: ctor taking range is O(n log n) even if the range is sorted Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: SWElef at post dot sk CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19422
[Bug libstdc++/19422] assoc. containers: ctor taking range is O(n log n) even if the range is sorted
-- What|Removed |Added Component|c++ |libstdc++ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19422
[Bug libstdc++/19422] assoc. containers: ctor taking range is O(n log n) even if the range is sorted
--- Additional Comments From SWElef at post dot sk 2005-01-13 16:59 --- Created an attachment (id=7953) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=7953action=view) performance test This is my test program. After giving it some thought I believe that calling the insert_unique/insert_equal function is wrong. I don't think that any hint (position) can help to make the running time linear in distance(first,last). A special function should be writen for this purpose. Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19422
[Bug c++/17648] [3.3/3.4 Regression] template destructor was not called for inherited classes
--- Additional Comments From SWElef at post dot sk 2004-12-20 17:09 --- (In reply to comment #13) Here's a condensed version of Wolfgang's testcase: int i=1; class A; templateint struct B { A *p; ~B() { --i; p=0; if(p) delete p; } }; class C : B0 {}; class A { C c; }; int main() { { C c; } return i; } This is not a condensed version of Wolfgang's testcase. While Wolfgang's testcase is well-formed, your is ill-formed. The difference is that it uses a pointer to object of _non-dependent_ incomplete type, i.e. it is invalid according to tc1:14.6/7: Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. If a type used in a non-dependent name is incomplete at a point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic required. [Note: ...] The details are very subtle because the template definition is not ill-formed by itself. std:5.3.5/5 says If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined. Thus, it would be well defined if the class A was later completed with trivial destructor and no class specific deallocation function. It is ill-formed because class A was incomplete at the point of definition of Bint::~B(), it was later defined with non-trivial destructor _and_ B0::~B() (with delete p;) was instantiated. For example the snippet from comment #14 _as short as it is_ is AFAICT well-formed. In this context it might be important to note that starting from gcc3.4 we have the two phase lookup. gcc3.4+ should be able to issue the same warning for the expression delete p; as for an ordinary delete expression involving an incomplete type. Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17648
[Bug c++/17648] [3.3/3.4 Regression] template destructor was not called for inherited classes
--- Additional Comments From SWElef at post dot sk 2004-12-17 11:12 --- AFAICT the code in comment #5 is well-formed. std:12.4/5: An implicitly-declared destructor is implicitly defined when it is used to destroy an object of its class type... Thus, the declaration+definition of class ObjectList only declares ObjectList::~ObjectList() and the implementation is not permitted to define it yet, which also means that the implementation is not permitted to instantiate ListTObject::~ListT(). The definition of class Object again only declares Object::~Object(). The first place where a destructor is used is the body of the function test where Object::~Object() must be implicitly defined. It forces the implicit definition of ObjectList::~ObjectList() and finaly the instantiation of ListTObject::~ListT(). At this point, however, the class Object is already defined so there is no undefined behaviour. (See also std:14.7.1/9 which forbids early instantiation of non-virtual member functions including the discussed dtor.) Note that during the instantiation of ListTObject::~ListT() the expression delete array; involves a call to _inline_ Object::~Object() that has not been defined yet (it is just waiting to be defined after its member's dtor's implicit definition is completed). I can imagine that this may cause some problems for the implementation but it does not affect the validity of the code. (Note in 7.1.2/4: a call to the inline function may be encountered before its definition appears in the translation unit.) Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17648
[Bug c++/18407] New: [Regression] ICE with mem-fun-ptr as template parameter for nested function template (build_base_path, cp/class.c)
ICE in g++ 3.4.0 (cygwin) and 3.4.3 (GNU C++ version 3.4.3 (i686-pc-cygwin)). OK for g++ 3.3.1 (GNU C++ version 3.3.1 (mingw special 20030804-1) (mingw32) and GNU C++ version 3.3.1 (cygming special) (i686-pc-cygwin)). Test case (legal code!): template typename Class struct the_base{ template void (Class::*Fn)() void foo() { } }; template typename T struct derivedT: the_basederivedTT { typedef the_basederivedTT parent; void ice(){ this-parent::template foo derivedTT::ice(); } }; int main() { derivedTint dT; dT.ice(); } Output (command line: c++ -v gccfail.cpp): ... GNU C++ version 3.4.3 (i686-pc-cygwin) compiled by GNU C version 3.4.0. ... gccfail.cpp: In member function `void derivedTT::ice() [with T = int]': gccfail.cpp:16: instantiated from here gccfail.cpp:10: internal compiler error: in build_base_path, at cp/class.c:275 ... Regards, Vladimir Marko -- Summary: [Regression] ICE with mem-fun-ptr as template parameter for nested function template (build_base_path, cp/class.c) Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: SWElef at post dot sk CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18407