Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there ever a valid reason to use C-style arrays in C++?

Tags:

c++

arrays

Between std::vector and std::array in TR1 and C++11, there are safe alternatives for both dynamic and fixed-size arrays which know their own length and don't exhibit horrible pointer/array duality.

So my question is, are there any circumstances in C++ when C arrays must be used (other than calling C library code), or is it reasonable to "ban" them altogether?

EDIT:

Thanks for the responses everybody, but it turns out this question is a duplicate of

Now that we have std::array what uses are left for C-style arrays?

so I'll direct everybody to look there instead.

[I'm not sure how to close my own question, but if a moderator (or a few more people with votes) wander past, please feel free to mark this as a dup and delete this sentence.]

like image 589
Tristan Brindle Avatar asked Oct 12 '14 16:10

Tristan Brindle


People also ask

What is a C style array?

One of the most common data structures, especially for scientific and numerical programming, is a group of variables all of the same type. This is frequently called an array.

Are C style arrays faster than vectors?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.

Should you ever use arrays in C++?

In “modern” C++ the word array must refer to std::array , and the word vector must refer to std::vector . Plain arrays should never be used unless for specific situation (like hardware mapping, or particular backward compatibilities).

Do you need to delete array C++?

You don't have to delete this array since you create it on stack. If you created the array using new then you would have to use delete to clean up.


2 Answers

I didnt want to answer this at first, but Im already getting worried that this question is going to be swamped with C programmers, or people who write C++ as object oriented C.

The real answer is that in idiomatic C++ there is almost never ever a reason to use a C style array. Even when using a C style code base, I usually use vectors. How is that possible, you say? Well, if you have a vector v and a C style function requires a pointer to be passed in, you can pass &v[0] (or better yet, v.data() which is the same thing).

Even for performance, its very rare that you can make a case for a C style array. A std::vector does involve a double indirection but I believe this is generally optimized away. If you dont trust the compiler (which is almost always a terrible move), then you can always use the same technique as above with v.data() to grab a pointer for your tight loop. For std::array, I believe the wrapper is even thinner.

You should only use one if you are an awesome programmer and you know exactly why you are doing it, or if an awesome programmer looks at your problem and tells you to. If you arent awesome and you are using C style arrays, the chances are high (but not 100%) that you are making a mistake,

like image 108
Nir Friedman Avatar answered Oct 11 '22 14:10

Nir Friedman


Foo data[] = {

is a pretty common pattern. Elements can be added to it easily, and the size of the data array grows based on the elements added.

With C++11 you can replicate this with a std::array:

template<class T, class... Args>
auto make_array( Args&&... args )
-> std::array< T, sizeof...(Args) >
{
  return { std::forward<Args>(args)... };
}

but even this isn't as good as one might like, as it does not support nested brackets like a C array does.

Suppose Foo was struct Foo { int x; double y; };. Then with C style arrays we can:

Foo arr[] = {
  {1,2.2},
  {3,4.5},
};

meanwhile

auto arr = make_array<Foo>(
  {1,2.2},
  {3,4.5}
};

does not compile. You'd have to repeat Foo for each line:

auto arr = make_array<Foo>(
  Foo{1,2.2},
  Foo{3,4.5}
};

which is copy-paste noise that can get in the way of the code being expressive.

Finally, note that "hello" is a const array of size 6. Code needs to know how to consume C-style arrays.

My typical response to this situation is to convert C-style arrays and C++ std::arrays into array_views, a range that consists of two pointers, and operate on them. This means I do not care if I was fed an array based on C or C++ syntax: I just care I was fed a packed sequence of data elements. These can also consume std::dynarrays and std::vectors with little work.

It did require writing an array_view, or stealing one from boost, or waiting for it to be added to the standard.

like image 26
Yakk - Adam Nevraumont Avatar answered Oct 11 '22 12:10

Yakk - Adam Nevraumont