public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible
@ 2012-05-05 20:14 dwalker07 at yahoo dot com
  2012-05-05 21:59 ` [Bug libstdc++/53248] " daniel.kruegler at googlemail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: dwalker07 at yahoo dot com @ 2012-05-05 20:14 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

             Bug #: 53248
           Summary: std::array<T,0> doesn't work when T is not
                    default-constructible
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: dwalker07@yahoo.com


(I'm using GCC 4.7.0 from MacPorts on my Mac OS X 10.4.11/Tiger (32-bit
PowerPC).)  Here's a reduced example of my code:

//==================================
#include <array>
#include <typeindex>
#include <typeinfo>

template < typename ...Types >
union super_union;

template < >
union super_union<>
{
    static  auto optioned_types() -> std::array<std::type_index, 0>
    { return std::array<std::type_index, 0>{ {} }; }
};

template < typename Head, typename ...Tail >
union super_union<Head, Tail...>
{
    static
    auto  optioned_types() -> std::array<std::type_index, 1 + sizeof...(Tail)>
    {
        using std::type_index;

        return { {type_index(typeid(Head)), type_index(typeid(Tail))...} };
    }

    Head                  data;
    super_union<Tail...>  rest;
};

int  main()  { return 0; }
//==================================

When I compile it, I get:

//==================================
[daryle]$ g++-mp-4.7 -std=c++11 test_array.cpp
test_array.cpp: In static member function 'static std::array<std::type_index,
0ul> super_union<>::optioned_types()':
test_array.cpp:12:49: error: could not convert '<brace-enclosed initializer
list>()' from '<brace-enclosed initializer list>' to
'std::array<std::type_index, 0ul>::value_type {aka std::type_index}'
//==================================

When I change the returned initialized value on line 12 to
"std::array<std::type_index, 0>{}", I get the same result.  But when I change
it to "std::array<std::type_index, 0>()", I get:

//==================================
[daryle]$ g++-mp-4.7 -std=c++11 test_array.cpp
test_array.cpp: In static member function 'static std::array<std::type_index,
0ul> super_union<>::optioned_types()':
test_array.cpp:12:45: error: use of deleted function
'std::array<std::type_index, 0ul>::array()'
In file included from test_array.cpp:1:0:
/opt/local/include/gcc47/c++/array:61:12: note: 'std::array<std::type_index,
0ul>::array()' is implicitly deleted because the default definition would be
ill-formed:
/opt/local/include/gcc47/c++/array:61:12: error: no matching function for call
to 'std::type_index::type_index()'
/opt/local/include/gcc47/c++/array:61:12: note: candidates are:
In file included from test_array.cpp:2:0:
/opt/local/include/gcc47/c++/typeindex:51:5: note:
std::type_index::type_index(const std::type_info&)
/opt/local/include/gcc47/c++/typeindex:51:5: note:   candidate expects 1
argument, 0 provided
/opt/local/include/gcc47/c++/typeindex:49:10: note: constexpr
std::type_index::type_index(const std::type_index&)
/opt/local/include/gcc47/c++/typeindex:49:10: note:   candidate expects 1
argument, 0 provided
/opt/local/include/gcc47/c++/typeindex:49:10: note: constexpr
std::type_index::type_index(std::type_index&&)
/opt/local/include/gcc47/c++/typeindex:49:10: note:   candidate expects 1
argument, 0 provided
//==================================

Looking at <array> on the web at your documentation pages, there is no
specialization of "std::array<T,N>" for "std::array<T,0>"; you just nudge the
element count to 1 when it would have been zero.  That secret element still
needs to be specified, since std::type_index doesn't have a default
constructor, although no initializers are logically necessary for an empty
array (i.e. the work-around abstraction leaks).

The first way I see around it is to make an explicit specialization that's
data-less.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
@ 2012-05-05 21:59 ` daniel.kruegler at googlemail dot com
  2012-05-05 23:57 ` paolo.carlini at oracle dot com
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-05 21:59 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

Daniel Krügler <daniel.kruegler at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.kruegler at
                   |                            |googlemail dot com

--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-05 21:16:36 UTC ---
(In reply to comment #0)
> Looking at <array> on the web at your documentation pages, there is no
> specialization of "std::array<T,N>" for "std::array<T,0>"; you just nudge the
> element count to 1 when it would have been zero.  That secret element still
> needs to be specified, since std::type_index doesn't have a default
> constructor, although no initializers are logically necessary for an empty
> array (i.e. the work-around abstraction leaks).
> 
> The first way I see around it is to make an explicit specialization that's
> data-less.

While I completely agree with your suggestion but I need to say that
unfortunately this is not what the library specification requires. The current
wording in fact allows implementations of the form found here. There is (again:
unfortunately) nothing that requires that std::array<T, 0> shall be
default-constructible irrespective of whether T is default-constructible, for
example.

I cannot speak for the decisions made in libstdc++ in regard to std::array's
optimized zero-size support, but I would like to encourage you to submit a
library issue to the email-address in the beginning of

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html

for this matter. I really think that it should be required that std::array<T,
0> is always default-constructible.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
  2012-05-05 21:59 ` [Bug libstdc++/53248] " daniel.kruegler at googlemail dot com
@ 2012-05-05 23:57 ` paolo.carlini at oracle dot com
  2012-05-06 11:41 ` daniel.kruegler at googlemail dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-05-05 23:57 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #2 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-05-05 23:27:26 UTC ---
The basic design of our std::array is rather old, dates back to the tr1::array
times, with updates. I bet we simply overlooked this issue, in terms of QoI.
Daniel, can you see other options besides adding a specialization? (which would
be a straightforward task, I may even get around to do pretty soon when I will
do debug-mode std::array, already in my todo list)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
  2012-05-05 21:59 ` [Bug libstdc++/53248] " daniel.kruegler at googlemail dot com
  2012-05-05 23:57 ` paolo.carlini at oracle dot com
@ 2012-05-06 11:41 ` daniel.kruegler at googlemail dot com
  2012-05-06 15:42 ` paolo.carlini at oracle dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-06 11:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #3 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-06 11:21:47 UTC ---
(In reply to comment #2)
> Daniel, can you see other options besides adding a specialization? (which would
> be a straightforward task, I may even get around to do pretty soon when I will
> do debug-mode std::array, already in my todo list)

I haven't implemented it completely, but an alternative to a partial
specialization could be something like the following:

template <class T, size_t N>
struct __array_data_traits
{
  typedef T type[N];
};

template <class T>
struct __array_data_traits<T, 0>
{
  struct type {};
};

template <class T, size_t N>
struct array
{
  typename __array_data_traits<T, N>::type elems;
};

array<int, 1> ai1 = {1};
array<int, 1> ai1b = {};
array<int, 0> ai0 = {};

The sole (?) disadvantage of this approach would be that
std::is_empty<array<int, 0>> does not evaluate to true. But all the
specialization-relevant logic could also be added to __array_data_traits in
terms of static (constexpr where possible) functions.

Technically the traits-based approach would be preferable, because otherwise I
see the risk that user-code that itself would try to specialize std::array with
some T for a user-provided type could notice the difference. Consider:

// Within Library:
template <class T, size_t N>
struct array
{
  T elems[N];
};

template <class T>
struct array<T, 0>
{
};

// User world:
struct User {};

template <size_t N>
struct array<User, N>
{
  User elems[N > 0 ? N : 1];
};

array<User, 0> au0 = {}; // Error, ambiguous

The problem with the current library wording is that it does not *explicitly*
allow a *specialization* for std::array (in contrast to vector<bool> or to
numeric_limits for cv-variations of the actual type), therefore I believe that
from the current wording state a partial-specialization by the library is
borderline to invalid, at least a gray zone, because of the need to support
[namespace.std] p1.

If a library issue should be submitted, I would suggest to provide the library
the freedom for providing a special for the zero-size case.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (2 preceding siblings ...)
  2012-05-06 11:41 ` daniel.kruegler at googlemail dot com
@ 2012-05-06 15:42 ` paolo.carlini at oracle dot com
  2012-05-06 18:56 ` paolo.carlini at oracle dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-05-06 15:42 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #4 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-05-06 15:39:33 UTC ---
Thanks Daniel. Since we had this issue for so much time, I guess we could as
well wait a bit for the Committee to provide some feedback about the
specialization option: in case there are no objections, just go with that. I
would rather stay away from std::is_empty false, if we are fixing this.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (3 preceding siblings ...)
  2012-05-06 15:42 ` paolo.carlini at oracle dot com
@ 2012-05-06 18:56 ` paolo.carlini at oracle dot com
  2012-05-06 19:19 ` daniel.kruegler at googlemail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-05-06 18:56 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2012-05-06
     Ever Confirmed|0                           |1

--- Comment #5 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-05-06 18:47:12 UTC ---
By the way - I think we discussed this already, bu now I can't find anything -
what should we take the begin() == end() == unique value exactly to mean? Don't
tell me something like an ugly reinterpret_cast<T*>(this), please


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (4 preceding siblings ...)
  2012-05-06 18:56 ` paolo.carlini at oracle dot com
@ 2012-05-06 19:19 ` daniel.kruegler at googlemail dot com
  2012-05-06 19:56 ` paolo.carlini at oracle dot com
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-05-06 19:19 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #6 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-06 18:56:05 UTC ---
(In reply to comment #5)
> By the way - I think we discussed this already, bu now I can't find anything -
> what should we take the begin() == end() == unique value exactly to mean? Don't
> tell me something like an ugly reinterpret_cast<T*>(this), please

My interpretation is that returning nullptr should be OK. I don't see any
requirement that a unique value is something that cannot be returned by any
other container (In a private communication with Howard he at least agreed with
my interpretation). If this interpretation is unsafe, it should also be
clarified by revised wording.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (5 preceding siblings ...)
  2012-05-06 19:19 ` daniel.kruegler at googlemail dot com
@ 2012-05-06 19:56 ` paolo.carlini at oracle dot com
  2012-10-01 23:44 ` paolo.carlini at oracle dot com
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-05-06 19:56 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #7 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-05-06 19:27:56 UTC ---
Good, good then. Personally, I find that "unique value" confusing.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (6 preceding siblings ...)
  2012-05-06 19:56 ` paolo.carlini at oracle dot com
@ 2012-10-01 23:44 ` paolo.carlini at oracle dot com
  2012-10-04  0:02 ` paolo at gcc dot gnu.org
  2012-10-04  0:03 ` paolo.carlini at oracle dot com
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-10-01 23:44 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
         AssignedTo|unassigned at gcc dot       |paolo.carlini at oracle dot
                   |gnu.org                     |com
   Target Milestone|---                         |4.8.0

--- Comment #8 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-10-01 23:44:25 UTC ---
I'm handling this.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (7 preceding siblings ...)
  2012-10-01 23:44 ` paolo.carlini at oracle dot com
@ 2012-10-04  0:02 ` paolo at gcc dot gnu.org
  2012-10-04  0:03 ` paolo.carlini at oracle dot com
  9 siblings, 0 replies; 11+ messages in thread
From: paolo at gcc dot gnu.org @ 2012-10-04  0:02 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

--- Comment #9 from paolo at gcc dot gnu.org <paolo at gcc dot gnu.org> 2012-10-04 00:02:33 UTC ---
Author: paolo
Date: Thu Oct  4 00:02:29 2012
New Revision: 192056

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192056
Log:
2012-10-03  Paolo Carlini  <paolo.carlini@oracle.com>

    PR libstdc++/53248
    * include/std/array (__array_traits<>): Add.
    (array<>): Allow for zero-size arrays of non default-constructible
    elements.
    * testsuite/23_containers/array/requirements/
    non_default_constructible.cc: New.
    * testsuite/23_containers/array/requirements/zero_sized_arrays.cc:
    Adjust.
    * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust
    dg-error line numbers.
    * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
    Likewise.

Added:
   
trunk/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/array
   
trunk/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc
    trunk/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
   
trunk/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/53248] std::array<T,0> doesn't work when T is not default-constructible
  2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
                   ` (8 preceding siblings ...)
  2012-10-04  0:02 ` paolo at gcc dot gnu.org
@ 2012-10-04  0:03 ` paolo.carlini at oracle dot com
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2012-10-04  0:03 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |FIXED

--- Comment #10 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-10-04 00:03:26 UTC ---
Fixed.


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2012-10-04  0:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-05 20:14 [Bug libstdc++/53248] New: std::array<T,0> doesn't work when T is not default-constructible dwalker07 at yahoo dot com
2012-05-05 21:59 ` [Bug libstdc++/53248] " daniel.kruegler at googlemail dot com
2012-05-05 23:57 ` paolo.carlini at oracle dot com
2012-05-06 11:41 ` daniel.kruegler at googlemail dot com
2012-05-06 15:42 ` paolo.carlini at oracle dot com
2012-05-06 18:56 ` paolo.carlini at oracle dot com
2012-05-06 19:19 ` daniel.kruegler at googlemail dot com
2012-05-06 19:56 ` paolo.carlini at oracle dot com
2012-10-01 23:44 ` paolo.carlini at oracle dot com
2012-10-04  0:02 ` paolo at gcc dot gnu.org
2012-10-04  0:03 ` paolo.carlini at oracle dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).