I have some classes designed to hold a pointer to some variables, and some other properties which are related to variables. Actually, I'm trying to design a CANopen stack for STM32 and I'm planning to use these classes to represent the object dictionary.
Here are the simplified versions of the classes:
class Object {
public:
constexpr Object(int index) : index{index} {}
private:
int index;
};
class Single : public Object {
public:
constexpr Single(int index, void* var, std::size_t size)
: Object{index}, ptr{var}, size{size} {}
private:
void* ptr;
std::size_t size;
};
class Array : public Object {
public:
constexpr Array(int index, void* var, std::size_t size, std::size_t length)
: Object{index}, ptr{var}, size{size}, length{length} {}
private:
void* ptr;
std::size_t size;
std::size_t length;
};
And I wish to create an array of these objects. The code below compiles without problems:
int a {1}; // Single variable
float b[] {2.0, 3.0}; // Array
const Object* dictionary[] {
new Single(0x1000, &a, sizeof(int)),
new Array(0x1001, b, sizeof(float), std::size(b))
};
The problem is, I try to avoid using heap (dynamic allocation) as much as possible. Usage of dynamic allocation in embedded systems is a debated subject, but my main concern is memory utilization: STM32 microcontrollers have a lot more flash ROM than they have RAM, so it's preferable to mark variables as const
, so the linker can place them into ROM instead of RAM.
But when a modify the code as below, it doesn't compile:
const Object* dictionary[] {
&Single(0x1000, &a, sizeof(int)),
&Array(0x1001, b, sizeof(float), std::size(b))
};
It gives error: taking address of rvalue
error.
I can think of one solution:
const Single a_obj {0x1000, &a, sizeof(int)};
const Array b_obj {0x1001, b, sizeof(float), std::size(b)};
const Object* dictionary[] {
&a_obj,
&b_obj
};
This works without problems, and places a_obj
& b_obj
into ROM. But I think it looks ugly. It forces me to define and maintain additional set of variables, and imagine what if you have maybe ~20 of them. Is there a cleaner way?