Topic: Implementation of array<T, N>


Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 30 Nov 2009 12:21:45 CST
Raw View
Hello all. I wonder what should happen if we create an array of zero
elements, as supported by 23.3.1.6:

   array<U, 0> a;

Is the implementation allowed to contain some code like the following:

   U elems[N == 0 ? 1 : N]; // allow zero size

Or must the implementation enforce that zero constructor calls of T happen?
If yes (it must enforce), how can it do that? Is it allowed to declare a
partial specialization for array<T, 0> ?

I'm wondering about this, since we are allowed to partially specialize a
template of std:: if it depends on a user defined type by 17.6.3.2.1. If the
programmer adds a specialization for his type, say "array<MyThingy, N>", and
using the array will then be ambiguous because it matches equally well for
"array<MyThingy, 0>" as does the implementation's specialization - whose
fault will it be based on the current wording of n3000 ? The one of the
programmer, or the one of the implementation?

Thanks all.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 30 Nov 2009 23:53:52 CST
Raw View
On 30 Nov., 19:21, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Hello all. I wonder what should happen if we create an array of zero
> elements, as supported by 23.3.1.6:
>
>    array<U, 0> a;
>
> Is the implementation allowed to contain some code like the following:
>
>    U elems[N == 0 ? 1 : N]; // allow zero size
>
> Or must the implementation enforce that zero constructor calls of T happen?

There is no such requirement, but there is also nothing which prevents
an implementation doing this. (But there is a gray zone in which way
the
current wording "begin() == end() == unique value" has to be
interpreted)

> If yes (it must enforce), how can it do that? Is it allowed to declare a
> partial specialization for array<T, 0> ?

I think the standard quite clearly specifies that such a
specialization
exists, as specified in [array.zero]:

1 array shall provide support for the special case N == 0.
2 In the case that N == 0, begin() == end() == unique value. The
return value of data() is unspecified.
3 The effect of calling front() or back() for a zero-sized array is
implementation-defined.

You could argue that it is astonishing that the standard does not
explicitly declare a partial specialization

template <class T> class array<T, 0>;

and I agree that this could be clearer.

> I'm wondering about this, since we are allowed to partially specialize a
> template of std:: if it depends on a user defined type by 17.6.3.2.1. If the
> programmer adds a specialization for his type, say "array<MyThingy, N>", and
> using the array will then be ambiguous because it matches equally well for
> "array<MyThingy, 0>" as does the implementation's specialization - whose
> fault will it be based on the current wording of n3000 ? The one of the
> programmer, or the one of the implementation?

I don't think that the standard could be currently read differently as
that an implementation is required to add a partial specialization
for N == 0. Given this, a user cannot expect that his or her own
partial
specialization

template<size_t N>
struct array<MyThingy, N>{ ... };

would just work without also providing a similar specialization

template<>
struct array<MyThingy, 0>{ ... };

So, a simple solution for this problem exists.

HTH & Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Niels Dekker - no reply address" <invalid@this.is.invalid>
Date: Mon, 30 Nov 2009 23:54:00 CST
Raw View
Johannes Schaub (litb) wrote:
> Is the implementation allowed to contain some code like the following:
>
>   U elems[N == 0 ? 1 : N]; // allow zero size
>
> Or must the implementation enforce that zero constructor calls of T
> happen? If yes (it must enforce), how can it do that? Is it allowed
> to declare a partial specialization for array<T, 0> ?
>
> I'm wondering about this, since we are allowed to partially
> specialize a template of std:: if it depends on a user defined type
> by 17.6.3.2.1. If the programmer adds a specialization for his type,
> say "array<MyThingy, N>", and using the array will then be ambiguous
> because it matches equally well for "array<MyThingy, 0>" as does the
> implementation's specialization - whose fault will it be based on the
> current wording of n3000 ? The one of the programmer, or the one of
> the implementation?

Excuse me, but why would you actually *want* to adds an std::array
specialization for your type, like std::array<MyThingy, N>?


Kind regards, Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Tue, 1 Dec 2009 13:06:39 CST
Raw View
Niels Dekker - no reply address wrote:

> Johannes Schaub (litb) wrote:
>> Is the implementation allowed to contain some code like the following:
>>
>>   U elems[N == 0 ? 1 : N]; // allow zero size
>>
>> Or must the implementation enforce that zero constructor calls of T
>> happen? If yes (it must enforce), how can it do that? Is it allowed
>> to declare a partial specialization for array<T, 0> ?
>>
>> I'm wondering about this, since we are allowed to partially
>> specialize a template of std:: if it depends on a user defined type
>> by 17.6.3.2.1. If the programmer adds a specialization for his type,
>> say "array<MyThingy, N>", and using the array will then be ambiguous
>> because it matches equally well for "array<MyThingy, 0>" as does the
>> implementation's specialization - whose fault will it be based on the
>> current wording of n3000 ? The one of the programmer, or the one of
>> the implementation?
>
> Excuse me, but why would you actually *want* to adds an std::array
> specialization for your type, like std::array<MyThingy, N>?
>

I was just thinking about it in theoretical means. There is no immediate
practical reason for me to do this, currently.

The issue came up when eelis tried to use "array<tracked::B, 0>" with
geordi, which printed one con/destructor call, which surprised us, since we
expected a similar result to "new tracked::B[0]" (as from the ctor/dtor
calls). Since this does not seem to be covered by the RVO paragraphs, i
wasn't sure whether this is something allowed to an implementation to do?
(spurious calls to constructors, etc?).

Looking it up, i spotted GCC doing the conditional-expression dance.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Leigh Johnston" <leigh@i42.co.uk>
Date: Tue, 1 Dec 2009 13:06:58 CST
Raw View
What is ambiguous exactly?  The following compiles/runs fine:

template <typename T, size_t N>
struct foo
{
foo() { std::cout << "a"; }
};

template <typename T>
struct foo<T, 0>
{
foo() { std::cout << "b"; }
};

template <size_t N>
struct foo<int, N>
{
foo() { std::cout << "c"; }
};

template <>
struct foo<int, 0>
{
foo() { std::cout << "d"; }
};

int main( )
{
foo<char, 0> f1;
foo<char, 1> f2;
foo<int, 0> f3;
foo<int, 1> f4;
}



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Daniel_Kr=3D FCgler?=3D <daniel.kruegler@googlemail.com>
Date: Tue, 1 Dec 2009 16:36:49 CST
Raw View
On 1 Dez., 06:53, Daniel Kr=FCgler <daniel.krueg...@googlemail.com>
wrote:
> On 30 Nov., 19:21, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>
> > Hello all. I wonder what should happen if we create an array of zero
> > elements, as supported by 23.3.1.6:
>
> >    array<U, 0> a;
>
> > Is the implementation allowed to contain some code like the following:
>
> >    U elems[N == 0 ? 1 : N]; // allow zero size
>
> > Or must the implementation enforce that zero constructor calls of T
happen?
>
> There is no such requirement, but there is also nothing which prevents
> an implementation doing this. (But there is a gray zone in which way
> the
> current wording "begin() == end() == unique value" has to be
> interpreted)
>
> > If yes (it must enforce), how can it do that? Is it allowed to declare =
a
> > partial specialization for array<T, 0> ?
>
> I think the standard quite clearly specifies that such a
> specialization
> exists, as specified in [array.zero]:
>
> 1 array shall provide support for the special case N == 0.
> 2 In the case that N == 0, begin() == end() == unique value. =
The
> return value of data() is unspecified.
> 3 The effect of calling front() or back() for a zero-sized array is
> implementation-defined.
>
> You could argue that it is astonishing that the standard does not
> explicitly declare a partial specialization
>
> template <class T> class array<T, 0>;
>
> and I agree that this could be clearer.

I think my previous conclusion was incorrect and as currently
specified their is no requirement for a partial specialization.

Nevertheless such an implementation technique seems conforming
to me and my suggestion to prevent possible ambiguities is to
provide an explicit specialization for (N==0, MyThingy) as described
in my previous reply.

Greetings from Bremen,

Daniel Kr=FCgler




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Wed, 2 Dec 2009 22:22:27 CST
Raw View
Leigh Johnston wrote:

> What is ambiguous exactly?  The following compiles/runs fine:
>

I think i could have been clearer with my wording. What i meant is that you
end up having one implementation defined partial specialization with "<T,
0>" and one you write yourself with "<int, N>". Then a reference to type
"foo<int, 0>" is ambiguous.

In your code, you had an additional explicit specialization for "<int, 0>",
which renders this all fine. I was/am in the impression that the Standard
allows one to write only one specialization and it should work as long as it
adheres to the required behavior and not result in strangeness like this
ambiguity.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "R.o.E" <rockonedge@gmail.com>
Date: Thu, 3 Dec 2009 12:01:30 CST
Raw View
Since it's not mentioned by others yet, I guess It's helpful to add
this link by Herb Sutter:
http://herbsutter.wordpress.com/2009/09/02/when-is-a-zero-length-array-okay/
On 12      1      ,             2  21      , "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Hello all. I wonder what should happen if we create an array of zero
> elements, as supported by 23.3.1.6:
>
>    array<U, 0> a;
>
> Is the implementation allowed to contain some code like the following:
>
>    U elems[N == 0 ? 1 : N]; // allow zero size
>
> Or must the implementation enforce that zero constructor calls of T happen?
> If yes (it must enforce), how can it do that? Is it allowed to declare a
> partial specialization for array<T, 0> ?
>
> I'm wondering about this, since we are allowed to partially specialize a
> template of std:: if it depends on a user defined type by 17.6.3.2.1. If the
> programmer adds a specialization for his type, say "array<MyThingy, N>", and
> using the array will then be ambiguous because it matches equally well for
> "array<MyThingy, 0>" as does the implementation's specialization - whose
> fault will it be based on the current wording of n3000 ? The one of the
> programmer, or the one of the implementation?
>
> Thanks all.
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]