Changing global array declarations to use the heap instead of BSS
Given global array declarations such as int a[10];
I would like to change the default storage from BSS to the heap in some old code for instrumentation reasons. This partially works:
int *a = new int[10]{};
Except that the size info is lost which precludes using a
in a range for statement among other things.
This, however, works and produces no errors or warnings in GCC or Clang with -pedantic. But I don't like using reinterpret_cast
.
int(&a)[10] = reinterpret_cast<int(&)[10]>(*new int[10]{});
Full code:
#include <iostream>
int a[10]; // zero initialized array in the BSS
int(&b)[10] = reinterpret_cast<int(&)[10]>(*new int[10]{}); // zero initialized array on the heap
int main()
{
// both a and b have the size of an array of 10 ints and can be used interchangably
a[1] = b[2] = 3;
for (auto&& x : b) // and both can use the range based for
x = 1;
static_assert(sizeof(a) == sizeof(b), "Not the same size");
std::cout << sizeof(a) << " " << sizeof(b) << '\n';
delete[] &b[0]; // unnecessary when just replacing BSS with heap for globals
}
The code produces the same assy for the two global arrays. https://godbolt.org/z/fbjzWvnev
Is reinterpret_cast
unavoidable to do this or is there some cleaner way?
While this will not work for all possible usages of b
, at the very least, everything in your posted question can also work with std::array
.
So you could do:
#include <array>
#include <iostream>
int a[10]; // zero initialized array in the BSS
std::array<int, 10> &b = *new std::array<int, 10>();
int main()
{
// both a and b have the size of an array of 10 ints and can be used interchangably
a[1] = b[2] = 3;
for (auto&& x : b) // and both can use the range based for
x = 1;
static_assert(sizeof(a) == sizeof(b), "Not the same size");
std::cout << sizeof(a) << " " << sizeof(b) << '\n';
delete &b; // unnecessary when just replacing BSS with heap for globals
}