0

I want to initialize an array of doubles in a separate function and pass the result back to the caller. At compile time I do not know the exact size, I just know it is small (1-100). I assume that the most efficient way is to allocate the memory on stack at the caller site and pass it to the function. Can I do this in a functional programming style as well without much performance overhead? For instance, returning a std::vector<double> instance would require a heap allocation. Alternatively, one could return an instance of boost::container::small_vector, which would avoid the heap allocation, but requires using boost. Is there any other way to do this?

int main() {
  auto size = calculateSize();
  
  // version 1: most efficient I guess
  //  double data[size];
  double* data = (double*)alloca(sizeof(double) * size);
  initData(data, size);
  
  // version 2 - what type should data2 have to minimize overhead with respect to first version?
  auto data2 = initData(size);
}

Update Adjusted stack memory allocation to make it standard conform c++.

This question is not about variable length arrays but about good alternatives to avoid heap allocation when returning small arrays from functions.

MarkusParker
  • 1,264
  • 2
  • 17
  • 35
  • if size is not known at compile time, you simply **can't** avoid heap allocation – Raildex May 19 '23 at 14:30
  • Is `size` something that you will only know at runtime? – NathanOliver May 19 '23 at 14:32
  • 1
    *but requires using boost* -- If you can't use boost, look at the boost source code to see how they accomplish `small_vector`. Then create your own class based on this information. Boost is still standard C++, they are not using anything that you could not write yourself. – PaulMcKenzie May 19 '23 at 14:34
  • why don't you try declaring a template vector that construct array with your specific size ! – Mahdi Zeinali May 19 '23 at 14:34
  • In modern C++ there is no particular overhead to return a vector. The vector will not be copied just because it is returned. Research *return value optimization* (RVO) – john May 19 '23 at 14:34
  • 2
    `double data[size];` -- Of course this is not valid C++ code if `size` is a runtime value. – PaulMcKenzie May 19 '23 at 14:35
  • 2
    No, C++ itself does not allow variable length arrays. What you are relying on is a specific compiler extension – Raildex May 19 '23 at 14:41
  • Unfortunately there is no such thing as `small_vector` in the standard library and `std::vector` can't be implemented with a small buffer optimization, because it is required that `std::vector`'s move operations don't invalidate iterators. If you don't want to use third party libraries or implement it yourself as suggested in the other comments, you could use `std::variant, std::vector>` ;-) – chrysante May 19 '23 at 14:45
  • @MarkusParker Turn on the `-pedantic` compiler option to get warnings about the use of non-Standard compiler extensions: https://godbolt.org/z/MKrWfbj8q GCC is one of a few compilers that allow Variable Length Arrays, likely to allow compilation of C code, where such arrays are legal. – user4581301 May 19 '23 at 14:45
  • True, some compiler accept it but it is not part of the standard. – MarkusParker May 19 '23 at 14:46
  • The following [answer](https://stackoverflow.com/questions/18530512/stl-boost-equivalent-of-llvm-smallvector#:~:text=I%20have%20designed%20my%20own%20version%20of%20SmallVector%20with%20move%20semantics.%20I%20have%20tried%20to%20keep%20it%20simple.%20It%20does%20not%20try%20to%20be%20exception%20safe.%20I%20also%20use%20unsigned%20integers%20for%20indexing%20as%20I%20prefer%20them%20over%20signed%20ones.%20Here%20is%20the%20code) provides a custom implementation for small vector – Karen Baghdasaryan May 19 '23 at 14:51
  • `double a[100]; ... std::span data(a, size);`??? Of course both `a` and `data` need to be returned together... – fabian May 19 '23 at 14:52
  • @fabian This would work, but then I would rather go with `small_vector`. – MarkusParker May 19 '23 at 14:56
  • You didn't want boost and with span you can get all of `std::span`'s members 25 loc (or 10 + (number of members of `std::span` that should be accessible) loc) without requiring anything other than the C++ standard library... – fabian May 19 '23 at 15:18

0 Answers0