Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a reason for zero sized std::array in C++11?

Consider the following piece of code, which is perfectly acceptable by a C++11 compiler:

#include <array> #include <iostream>  auto main() -> int {   std::array<double, 0> A;    for(auto i : A) std::cout << i << std::endl;    return 0; } 

According to the standard § 23.3.2.8 [Zero sized arrays]:

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 undefined.

4 Member function swap() shall have a noexcept-specification which is equivalent to noexcept(true).

As displayed above, zero sized std::arrays are perfectly allowable in C++11, in contrast with zero sized arrays (e.g., int A[0];) where they are explicitly forbidden, yet they are allowed by some compilers (e.g., GCC) in the cost of undefined behaviour.

Considering this "contradiction", I have the following questions:

  • Why the C++ committee decided to allow zero sized std::arrays?

  • Are there any valuable uses?

like image 749
101010 Avatar asked Jun 10 '14 23:06

101010


People also ask

Can you have an array of size 0 C++?

In the case of a zero sized array, no objects are created, and no address is required to be given, hence it falls (in my opinion) outside of the standard's description of an array, becoming a valid extension of the language. In other words, a zero sized array is not an array, but something else (an extension).

Can an array be size 0?

Although the size of a zero-length array is zero, an array member of this kind may increase the size of the enclosing type as a result of tail padding. The offset of a zero-length array member from the beginning of the enclosing structure is the same as the offset of an array with one or more elements of the same type.

Is std :: array initialize?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is. The outer set is for aggregate initialization.

What is the point of std :: array?

std::array is merely a wrapper around the C-style fixed arrays. to provide type-safety with useful interfaces. Stack-allocation implies that the data for the array is stored in the object itself.


2 Answers

If you have a generic function it is bad if that function randomly breaks for special parameters. For example, lets say you could have a template function that takes N random elements form a vector:

template<typename T, size_t N> std::array<T, N> choose(const std::vector<T> &v) {    ... } 

Nothing is gained if this causes undefined behavior or compiler errors if N for some reason turns out to be zero.

For raw arrays a reason behind the restriction is that you don't want types with sizeof T == 0, this leads to strange effects in combination with pointer arithmetic. An array with zero elements would have size zero, if you don't add any special rules for it.

But std::array<> is a class, and classes always have size > 0. So you don't run into those problems with std::array<>, and a consistent interface without an arbitrary restriction of the template parameter is preferable.

like image 188
sth Avatar answered Oct 06 '22 03:10

sth


One use that I can think of is the return of zero length arrays is possible and has functionality to be checked specifically.

For example see the documentation on the std::array function empty(). It has the following return value:

true if the array size is 0, false otherwise. 

http://www.cplusplus.com/reference/array/array/empty/

I think the ability to return and check for 0 length arrays is in line with the standard for other implementations of stl types, for eg. Vectors and maps and is therefore useful.

like image 37
Fantastic Mr Fox Avatar answered Oct 06 '22 03:10

Fantastic Mr Fox