3

Let's say I have the following std::array

#define MAX_SIZE(6)
typedef struct MyStruct
{
  int test_integer;
  float test_float;
} MyStruct_T

std::array<MyStruct_T, MAX_SIZE> my_array = { 0 }

Now there is a function that accepts C style array by address:

void MyFunction(MyStruct_T const (&input)[MAX_SIZE])

What is the right way to pass my_array to MyFunction?

If the function declaration/definition argument cannot be changed, what is the most efficient way to convert std::array to C style array? (I only see C style to std::array methods)

  • 2
    Does this answer your question? [Is the std::array bit compatible with the old C array?](https://stackoverflow.com/questions/39376813/is-the-stdarray-bit-compatible-with-the-old-c-array) – KagurazakaKotori Jun 02 '20 at 01:04
  • 2
    There's no good way. The function should be rewritten to accept a pointer and a size. – HolyBlackCat Jun 02 '20 at 01:05
  • If the function declaration/definition argument cannot be changed, what is the most efficient way to convert std::array to C style array? (I only see C style to std::array methods) – coffeenator Jun 02 '20 at 01:11
  • @coffeenator There isn't one, at least not standard conforming. In *practice*, reinterpreting a `std::array&` as a `MyStruct_T[MAX_SIZE]&`, or a `std::array*` as a `MyStruct_T[MAX_SIZE]*`, *will likely* work, but you should not rely on that. – Remy Lebeau Jun 02 '20 at 01:29
  • 1
    @RemyLebeau - I'd be more inclined to do such a cast on the pointer returned by the array's `data()` member. That said, I also wouldn't offer any guarantee that such a conversion is safe - I'd prefer rewriting `MyFunction()` to accept either a `std::array` argument, or a `MyStruct_T*` and a size. Apart from readability (code involving casts is a bear to get right, and too many "smart" developers have a habit of subsequently "improving" or "tidying" such a cast and breaking it) there is no room for debate over potential undefined behaviour due to attempts at type punning. – Peter Jun 02 '20 at 01:38
  • 1
    If you can rewrite the function, accepting `std::span` from C++20 (or from `gsl::span` from thee gsl library if you can't use c++20) can be a better option (more general) than accepting `std::array` or a pointer and a size. – darcamo Jun 02 '20 at 01:47
  • Thank you all. I ended up changing the function definition/declaration. – coffeenator Jun 02 '20 at 14:52
  • @RemyLebeau: `T[…]&` doesn’t parse: it’s `T(&)[…]` (and similarly for `*`). (Perhaps you know that and it’s a typo, but it should still be given correctly here.) – Davis Herring Jun 02 '20 at 19:09
  • I'm aware of that, I wrote it that way to make the point clearer without confusing beginners on the syntax. In this case, I would suggest making use of `using` statements to make it cleaner, eg: `using my_std_array = std::array; my_std_array my_array = {};` ... `using my_c_array = MyStruct_T[MAX_SIZE]; void MyFunction(const my_c_array &input)` Then you can do `MyFunction(reinterpret_cast(my_array));` or `MyFunction(*reinterpret_cast(&my_array));` – Remy Lebeau Jun 02 '20 at 19:41

0 Answers0