During programming an embedded system without MMU, I should not use heap (because of memory fragmentation problem).
Part of the software is written in C (drivers) and the logic is written in C++ subset without dynamic allocation of memory.
Because of unit testing the default constructor is deleted. Instead - there is single parameter constructor with reference to structure of driver function pointers.
driver.h: (the pure C module)
#pragma once
bool Init();
uint32_t ReadMeasurement();
module.hpp: (the C++ part)
class Module {
public:
struct DriverApi {
void (*Init)();
uint32_t (*ReadData)();
};
Module() = delete;
explicit Module(DriverApi &aDriverApi);
private:
DriverApi& mDriverApi;
};
The module manager:
module_manager.hpp:
class ModuleManager {
// (...)
private:
Module::DriverApi module_1; // I can't declare this in this way
Module::DriverApi module_2; // because of lack of default constructor.
Module::DriverApi module_3;
etc.
};
How to initialize module_1, module_2 and module_3 without using heap? And n parameters constructor?
Options I'm aware:
It look's easy to use std::shared_ptr, but then std::make_shared use heap.
I can leave default constructor and then call sth. like Init(Module::DriverApi *aDriverApi) but this "violates" RAII.
Is there any other way to create "elegant" and embedded safe initialization?
Either use a default constructor or write one with named parameters. If you need to initialize members to non-zero values but don't have access to such values because the constructor has too few parameters, the constructor is incorrectly designed.
Because of unit testing the default constructor is deleted
Tests are supposed to make the product better - get rid of them if they do the opposite.
Normally any embedded system has a fixed set of drivers. So normally it would make little sense to have those as non-static members. Making a driver class per hardware peripheral present makes sense. Then a static instance for each instance of that hardware present on the target. You don't need to cover hardware which is never going to be present, nor will the hardware change dynamically in run-time. In fact a large part of it ought to be const and be stored in flash.
RAII has limited use on single core, single process embedded systems since your program needs to be deterministic and it owns all resources on the MCU. You usually never need to free up anything, all you need is to allocate as much memory as the product needs.
Keep it simple. Don't invent abstraction layers that fill no purpose.
I just put your code in IDE, and it compiles.
What I can identify in your program:
if you try to assign bool Init(); to the void (*Init)(), please change the return type.
When a user-defined constructor is defined, the default constructor is already deleted implicitly. What is missing is that you have to initialize the member.
Try explicit Module(DriverApi &aDriverApi):mDriverApi{aDriverApi}{}
class Module {
public:
struct DriverApi {
void (*Init)();
uint32_t (*ReadData)();
};
Module() = delete;
explicit Module(DriverApi &aDriverApi):mDriverApi{aDriverApi}{}
private:
DriverApi& mDriverApi;
};
void fun(){
std::cout<<"This is fun\n";
}
int main(){
Module::DriverApi module_1; // I can't declare this in this way because of lack of default constructor.
module_1.Init = fun;
module_1.Init();
Module m{module_1};
return 0;
}
Related
I have been developing a C++ software driver for the adc peripheral of the MCU.
The individual analog inputs connected to the adc can be configured for operation in the unipolar or bipolar mode. To reflect this fact in my design I have decided to model the analog inputs by the AnalogInput abstract class and then define two derived classes. UnipolarAnalogInput for the unipolar analog inputs and BipolarAnalogInput for the bipolar analog inputs. These two classes differ only in the implementation of the getValue() method.
enum class Type
{
Unipolar,
Bipolar
};
class AnalogInput
{
public:
virtual float getValue() = 0;
};
class UnipolarAnalogInput : public AnalogInput
{
public:
UnipolarAnalogInput(uint8_t _id, bool _enabled, Type _type);
bool isEnabled();
bool isReady();
float getValue();
private:
uint8_t id;
Type type;
bool enabled;
bool ready;
uint16_t raw_value;
};
class BipolarAnalogInput : public AnalogInput
{
public:
BipolarAnalogInput(uint8_t _id, bool _enabled, Type _type);
bool isEnabled();
bool isReady();
float getValue();
private:
uint8_t id;
Type type;
bool enabled;
bool ready;
uint16_t raw_value;
};
My goal is to fullfill following requirements:
work with both types of the analog inputs uniformly
have a chance to create either the instance of the UnipolarAnalogInput or BipolarAnalogInput
based on users configuration of the Adc which is known at the compile time
have a chance to create the instances in for loop iteration
have the implementation which is suitable for the embedded systems
Here are my ideas
As far as the requirement 1.
The ideal state would be to have AnalogInput analog_inputs[NO_ANALOG_INPUTS]. As far as I understand
correctly this is not possible in C++. Instead of that I need to define AnalogInput *analog_inputs[NO_ANALOG_INPUTS].
As far as the requirement 2.
It seems to me that the best solution for the other systems than the embedded systems would be to use the factory method design pattern i.e. inside the AnalogInput define
static AnalogInput* getInstance(Type type) {
if(type == Unipolar) {
// create instance of the UnipolarAnalogInput
} else if(type == Bipolar) {
// create instance of the BipolarAnalogInput
}
}
Here I would probably need to define somewhere auxiliary arrays for the UnipolarAnalogInput instances and the BipolarAnalogInput instances where the instances would be allocated by the factory method and the pointers to those arrays would be returned by the getInstance(). This solution seems to me to be pretty cumbersome due to the auxiliary arrays presence.
As far as the requirement 3.
for(uint8_t input = 0; input < NO_ANALOG_INPUTS; input++) {
analog_inputs[input] = AnalogInput::getInstance(AdcConfig->getInputType(input));
}
As far as the requirement 4.
Here I would say that what I have suggested above is applicable also for the embedded systems
because the solution avoids usage of the standard new operator. Question mark is the virtual
method getValue().
My questions is whether the auxiliary arrays presence is unavoidable?
The "auxiliary array" as you call it is mostly needed for memory management, i.e. you need to choose the memory to store your objects in. It's also an interface - the array is how you access the ADCs.
You can store your objects either in the heap or the (global) data segment - an array of objects implements the latter (you can also create global variables, one per ADC, which is a worse solution). If the compiler has all the information it needs to allocate the memory during compilation, it's usually the preferred approach. However - as you've noticed - polymorphism becomes rather annoying to implement with statically allocated objects.
The alternative is to keep them in heap. This is often totally acceptable in an embedded system if you allocate the heap memory at startup and keep it permanently (i.e. never try to release or re-use this part of heap, which would risk fragmentation). And this is really the only humane way to do polymorphic stuff, especially object instantiation.
If you don't like the array, use some other storage method - linked list, global variables, whatever. But you need to access the objects through a pointer (or a reference, which is also a pointer) for polymorhpism to work. And arrays are a simple concept, so why not use them?
In my program I need a factory function that provides instances of separate class because I need control over the details of each instance and to be aware of how many instances are in existence at a time. In particular returning a std::shared_ptr is ideal, but this is initially impossible due to a known issue with the "make" fucntions of the std::pointer types as they would need to be friends with my Widget class as well, which isn't portable since it relies on the current implementation of those methods that may change.
To get around this, I want to employ the Passkey idiom, which was directly recommend for this situation as described at the bottom of this: https://abseil.io/tips/134. I also based my implementation off the lessons learned here: https://arne-mertz.de/2016/10/passkey-idiom/
This is a sample project that uses my same setup as my full project:
#include <iostream>
class Widget
{
public:
class Key
{
friend class Factory;
private:
Key() {};
Key(const Key&) = default;
};
int mTest;
explicit Widget(Key, int test) { mTest = test; }
int getTestVar() { return mTest; }
};
class Factory
{
public:
int mTestPass;
Factory(int input) { mTestPass = input; }
std::shared_ptr<Widget> factoryMake() { return std::make_shared<Widget>(Widget::Key{}, mTestPass); }
};
int main()
{
Factory testFactory(10);
std::shared_ptr<Widget> testWidget = testFactory.factoryMake();
std::cout << testWidget->getTestVar();
return 0;
}
However, I get
Error C2248 'Widget::Key::Key': cannot access private member declared in class 'Widget::Key' TestProject ...\include\xmemory 204
This has me completely lost, since the error coming from xmemory.cpp indicates that std::make_shared is sill trying to access a private constructor. As far as I'm aware, the construction of the Key instance occurs within the factoryMake() function, which belongs to Factory, and then that instance is passed into the std::make_shared function; therefore, std::make_shared should not need access to the Key constructor since an already constructed instance is being passed to it, which is the entire point of using this idiom in this context. The class itself is public so it should have no issues interacting with the type Key, only the constructor should be inaccessible.
In the end I can just skip using std::make_shared and instead use the shared_ptr(*T) constructor with a raw pointer, but this is slightly less efficient due to the extra allocation it requires, as noted in my first link. It isn't a big deal as I'm not making many widgets but I'd ultimately prefer to get the more ideal implementation working.
What am I missing here?
The problem is that the compiler needs to copy your Widget::Key when you call std::make_shared, and you have declared the copy constructor private. You can solve this in one of two ways:
Make the copy constructor of Widget::Key public.
Change the Widget constructor to take the Widget::Key by const reference:
explicit Widget(const Key&, ...
I was recently studying the source code of the ENTT library, and I came across something similar to the following snippet of code (note that I have greatly simplified things to make my question brief):
// Note that this class doesn't contain any member variables
class TextureLoader
{
public:
TextureLoader() = default;
~TextureLoader() = default;
std::shared_ptr<Texture> loadResource(const std::string& textureFilePath) const;
};
template<typename TResource, typename TResourceLoader, typename... Args>
std::shared_ptr<TResource> loadResource(Args&&... args)
{
// Note how a temporary TResourceLoader is created to invoke its loadResource member function
return TResourceLoader{}.loadResource(std::forward<Args>(args)...));
}
int main()
{
std::string texFilePath = "tex.png";
std::shared_ptr<Texture> myTexture = loadResource<Texture, TextureLoader>(texFilePath);
return 0;
}
As you can see, the loadResource function template is capable of loading any resource type (e.g. Texture, Shader, Model, Sound, etc.). The documentation of the library states that a loader class should ideally not contain any member variables. I imagine this is because every time loadResource is called, a temporary of the loader class passed to it is created to invoke its loadResource member function. And that's where my question lies: what is the cost of TResourceLoader{}.loadResource()? Is the compiler able to remove the creation of the temporary because it doesn't contain any member variables? Is there a better way to this?
There should be no significant performance implications, although code will be penalized ever so slightly. In order to understand the implications better, let's try to decompose the code into something which would be similar to compiler's generated code:
From:
return TResourceLoader{}.loadResource(std::forward<Args>(args)...));
To:
char Storage[1]; // Any object in C++ is at least 1 byte, including classes with no members
Storage(&Storage); // Pseudo-code illustrating calling constructor
loadResource(&Storage, <args>); // considering loadResource can't be inlined
Storage.~Storage();
In code above, compiler will see that both constructor and destructor are default, and since class has no member are, indeed, trivial - so those could be safely omitted.
What you end up with is a necessity to allocate 1 byte in automatic storage, which on modern architectures usually means decrementing stack pointer register, following by incrementing it.
This is incredibly fast operation, but it still not instantaneous.
Yes, the compiler will optimize out the creation of a temporary variable without any data members. There basically is no codegen required for that. You can verify it yourself and play with various optimization levels on an online tool like Compiler Explorer.
I'm writing a physics simulation (Ising model) in C++ that operates on square lattices. The heart of my program is my Ising class with a constructor that calls for the row and column dimensions of the lattice. I have two other methods to set other parameters of the system (temperature & initial state) that must get called before evolving the system! So, for instance, a sample program might look like this
int main() {
Ising system(30, 30);
system.set_state(up);
system.set_temperature(2);
for(int t = 0; t < 1000; t++) {
system.step();
}
return 0;
}
If the system.set_*() methods aren't called prior to system.step(), system.step() throws an exception alerting the user to the problem. I implemented it this way to simplify my constructor; is this bad practice?
It is recommended to put all mandatory parameters in the constructor whenever possible (there are exceptions of course, but these should be rare - I have seen one real-world example so far). This way you make your class both easier and safer to use.
Note also that by simplifying your constructor you make the client code more complicated instead, which IMO is a bad tradeoff. The constructor is written only once, but caller code may potentially need to be written many times more (increasing both the sheer amount of code to be written and the chance of errors).
Not at all, IMO. I face the same thing when loading data from external files. When the objects are created (ie, their respective ctors are called), the data is still unavailable and can only be retrieved at a later stage. So I split the initialisation in different stages:
constructor
initialisation (called by the framework engine when an object is activated for the first time)
activation (called each time an object is activated).
This is very specific to the framework I'm developing, but there is no way to deal with everything using just the constructor.
However, if you know the variables at the moment the ctor is called, it's better not to complicate the code. It's a possible source of headaches for anyone using your code.
IMO this is poor form if all of these initialization steps must be invoked every time. One of the goals of well-designed software is to minimize the opportunities to screw up, and having multiple methods which must be invoked before an object is "usable" simply makes it harder to get right. If these calls were optional then having them as separate methods would be fine.
Share and enjoy.
The entire point in a class is to present some kind of abstraction. As a user of a class, I should be able to assume that it behaves like the abstraction it models.
And part of that is that the class must always be valid. Once the object has been created (by calling the constructor), the class must be in a meaningful, valid state. It should be ready to use. If it isn't, then it is no longer a good abstraction.
If the initialization methods must be called in a specific order then I would wrap the call to them in their own method as this indicates that the methods are not atomic on their own so the 'knowledge' of how they should be called should be held in one place.
Well that's my opinion, anyway!
I'd say that setting the initial conditions should be separate from the constructor if you plan to initialize and run more than one transient on the same lattice.
If you run a transient and stop, then it's possible to move setting the initial conditions inside the constructor, but it means that you have to pass in the parameter values in order to do this.
I fully agree with the idea that an object should be 100% ready to be used after its constructor is called, but I think that's separate from the physics of setting the initial temperature field. The object could be fully usable, yet have every node in the problem at the same temperature of absolute zero. A uniform temperature field in an insulated body isn't of much interest from a heat transfer point of view.
As another commentator pointed out, having to call a bunch of initialisation functions is poor form. I would wrap this up in a class:
class SimulationInfo
{
private:
int x;
int y;
int state;
int temperature;
public:
SimulationArgs() : x(30), y (30), state(up), temperature(2) { }; // default ctor
// custom constructors here!
// properties
int x() const { return x; };
int y() const { return y; };
int state() const { return state; };
int temperature() const { return temperature; };
}; // eo class SimulationInfo
class Simulation
{
private:
Ising m_system;
public:
Simulation(const SimulationInfo& _info) : m_system(_info.x(), _info.y())
{
m_system.set_state(_info.state());
m_system.set_temperature(_info.temperature());
} // eo ctor
void simulate(int _steps)
{
for(int step(0); step < _steps; ++steps)
m_system.step();
} // eo simulate
}; // eo class Simulation
There are otherways, but this makes things infinitely more usable from a default setup:
SimulationInfo si; // accept all defaults
Simulation sim(si);
sim.simulate(1000);
Suppose you have the following code:
int main(int argc, char** argv) {
Foo f;
while (true) {
f.doSomething();
}
}
Which of the following two implementations of Foo are preferred?
Solution 1:
class Foo {
private:
void doIt(Bar& data);
public:
void doSomething() {
Bar _data;
doIt(_data);
}
};
Solution 2:
class Foo {
private:
Bar _data;
void doIt(Bar& data);
public:
void doSomething() {
doIt(_data);
}
};
In plain english: if I have a class with a method that gets called very often, and this method defines a considerable amount of temporary data (either one object of a complex class, or a large number of simple objects), should I declare this data as private members of the class?
On the one hand, this would save the time spent on constructing, initializing and destructing the data on each call, improving performance. On the other hand, it tramples on the "private member = state of the object" principle, and may make the code harder to understand.
Does the answer depend on the size/complexity of class Bar? What about the number of objects declared? At what point would the benefits outweigh the drawbacks?
From a design point of view, using temporaries is cleaner if that data is not part of the object state, and should be preferred.
Never make design choices on performance grounds before actually profiling the application. You might just discover that you end up with a worse design that is actually not any better than the original design performance wise.
To all the answers that recommend to reuse objects if construction/destruction cost is high, it is important to remark that if you must reuse the object from one invocation to another, in many cases the object must be reset to a valid state between method invocations and that also has a cost. In many such cases, the cost of resetting can be comparable to construction/destruction.
If you do not reset the object state between invocations, the two solutions could yield different results, as in the first call, the argument would be initialized and the state would probably be different between method invocations.
Thread safety has a great impact on this decision also. Auto variables inside a function are created in the stack of each of the threads, and as such are inherently thread safe. Any optimization that pushes those local variable so that it can be reused between different invocations will complicate thread safety and could even end up with a performance penalty due to contention that can worsen the overall performance.
Finally, if you want to keep the object between method invocations I would still not make it a private member of the class (it is not part of the class) but rather an implementation detail (static function variable, global in an unnamed namespace in the compilation unit where doOperation is implemented, member of a PIMPL...[the first 2 sharing the data for all objects, while the latter only for all invocations in the same object]) users of your class do not care about how you solve things (as long as you do it safely, and document that the class is not thread safe).
// foo.h
class Foo {
public:
void doOperation();
private:
void doIt( Bar& data );
};
// foo.cpp
void Foo::doOperation()
{
static Bar reusable_data;
doIt( reusable_data );
}
// else foo.cpp
namespace {
Bar reusable_global_data;
}
void Foo::doOperation()
{
doIt( reusable_global_data );
}
// pimpl foo.h
class Foo {
public:
void doOperation();
private:
class impl_t;
boost::scoped_ptr<impl_t> impl;
};
// foo.cpp
class Foo::impl_t {
private:
Bar reusable;
public:
void doIt(); // uses this->reusable instead of argument
};
void Foo::doOperation() {
impl->doIt();
}
First of all it depends on the problem being solved. If you need to persist the values of temporary objects between calls you need a member variable. If you need to reinitialize them on each invokation - use local temporary variables. It a question of the task at hand, not of being right or wrong.
Temporary variables construction and destruction will take some extra time (compared to just persisting a member variable) depending on how complex the temporary variables classes are and what their constructors and destructors have to do. Deciding whether the cost is significant should only be done after profiling, don't try to optimize it "just in case".
I'd declare _data as temporary variable in most cases. The only drawback is performance, but you'll get way more benefits. You may want to try Prototype pattern if constructing and destructing are really performance killers.
If it is semantically correct to preserve a value of Bar inside Foo, then there is nothing wrong with making it a member - it is then that every Foo has-a bar.
There are multiple scenarios where it might not be correct, e.g.
if you have multiple threads performing doSomething, would they need all separate Bar instances, or could they accept a single one?
would it be bad if state from one computation carries over to the next computation.
Most of the time, issue 2 is the reason to create local variables: you want to be sure to start from a clean state.
Like a lot of coding answers it depends.
Solution 1 is a lot more thread-safe. So if doSomething were being called by many threads I'd go for Solution 1.
If you're working in a single threaded environment and the cost of creating the Bar object is high, then I'd go for Solution 2.
In a single threaded env and if the cost of creating Bar is low, then I think i'd go for Solution 1.
You have already considered "private member=state of the object" principle, so there is no point in repeating that, however, look at it in another way.
A bunch of methods, say a, b, and c take the data "d" and work on it again and again. No other methods of the class care about this data. In this case, are you sure a, b and c are in the right class?
Would it be better to create another smaller class and delegate, where d can be a member variable? Such abstractions are difficult to think of, but often lead to great code.
Just my 2 cents.
Is that an extremely simplified example? If not, what's wrong with doing it this
void doSomething(Bar data);
int main() {
while (true) {
doSomething();
}
}
way? If doSomething() is a pure algorithm that needs some data (Bar) to work with, why would you need to wrap it in a class? A class is for wrapping a state (data) and the ways (member functions) to change it.
If you just need a piece of data then use just that: a piece of data. If you just need an algorithm, then use a function. Only if you need to keep a state (data values) between invocations of several algorithms (functions) working on them, a class might be the right choice.
I admit that the borderlines between these are blurred, but IME they make a good rule of thumb.
If it's really that temporary that costs you the time, then i would say there is nothing wrong with including it into your class as a member. But note that this will possibly make your function thread-unsafe if used without proper synchronization - once again, this depends on the use of _data.
I would, however, mark such a variable as mutable. If you read a class definition with a member being mutable, you can immediately assume that it doesn't account for the value of its parent object.
class Foo {
private:
mutable Bar _data;
private:
void doIt(Bar& data);
public:
void doSomething() {
doIt(_data);
}
};
This will also make it possible to use _data as a mutable entity inside a const function - just like you could use it as a mutable entity if it was a local variable inside such a function.
If you want Bar to be initialised only once (due to cost in this case). Then I'd move it to a singleton pattern.