简体   繁体   中英

code size of using std::array

I'm working on an embedded system (ARM Cortex-M0, so no Linux). I've written a lot of C code for embedded platforms, but this is my first foray into C++.

In my C code, arrays passed into functions always take up 2 parameters. One for the pointer to the data and a second with the length of the array. For example:

void write(uint8_t *buf, size_t bufLen, size_t writeLen);

I'm considering switching these to using std::array (introduced in C++11). It's attractive because it keeps track of its own length but doesn't do any allocation. It looks like the equivalent would be

template<size_t N> void write(array<uint8_t, N> *buf, size_t writeLen);

If my code ends up calling write with 10 differently-sized arrays, does the compiler end up defining 10 different functions? This seems possibly particularly bad if I define a function that takes two (or more) arrays, as the function has to be templated on 2 parameters (the size of each array):

template<size_t N, size_t M>
void readWrite(array<uint8_t, N> *readBuf,
               array<uint8_t, M> *writeBuf, size_t writeLen);

If write() code doesn't benefit much from knowing bufLen at compile time, then I don't see any point of changing it. I'd leave the original function prototype and add convenience wrappers on demand, like this:

template<size_t N>
void write(array<uint8_t, N> &buf, size_t count) {
    write(buf.data(), buf.size(), count);
}

You can add more for different buffer-like types, eg vector and string . In optimized builds all these wrappers will be trivial and inline, so no code duplication, although it's still worth checking after compilation.

The next step is to use array_view which isn't in standard yet. But you can borrow the implementation from somewhere or craft your own easily. With it, you can define principal function as

void write(array_view<uint8_t>, size_t);

And you don't even need any wrappers because array_view can be implicitly constructed from C arrays and various containers.

In theory, yes. However the template function has to be defined in the TU where it's used. This means it's easily inlined.

Still, also have a look at std::vector .

As long as what you're passing are really arrays (not pointers), you can accomplish roughly the same by rewriting the function as a template, but passing a reference to a raw array rather than an std::array . That gives us code like this:

template <size_t N>
void write(uint8_t (&buf)[N]);

So to call this, we could do something like:

uint8_t buffer[256];

write(buffer);

uint8_t buffer2[512];

write(buffer2);

...and in the first call, the compiler will deduce N as being 256, and in the second as being 512.

The basic effect is the same though--at least potentially, the compiler will still generate unique code for each size of array you pass.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM