I want to be able to configure a class to be able to access hardware in its member functions. Let's assume we have an avr device, where we simply can access hardware like PORTA = 0x00; which writes a 0x00 to the io memory space. The problem is generic for every kind of embedded memory io access, not specific to avr.
But if I want to now use a class which can be parametrized, it seems C++ has closed all the doors because it seems to be simply impossible to define any kind of pointer types and give them a constexpr value anymore.
Some compiler versions prior, we were able to run such code like: constexpr reference to avr port address
But now all tries to assign a value to pointer for a constexpr value fails, because reinterpret_cast can not longer be used in that case.
As a dirty hack I tried and failed:
struct ONE
{
static constexpr volatile uint8_t* helper=nullptr;
static constexpr volatile uint8_t* portc=&helper[100];
};
fails with:
x.cpp:6:57: error: arithmetic involving a null pointer in '0'
6 | static constexpr volatile uint8_t* portc=&helper[100];
Also fails:
// for AVR PORTB is defined in io.h like:
#define PORTB (*(volatile uint8_t *)((0x05) + 0x20))
constexpr volatile uint8_t* ptr=&PORTB;
Fails with:
x.cpp: In function 'int main()':
x.cpp:15:37: error: 'reinterpret_cast<volatile uint8_t* {aka volatile unsigned char*}>(56)' is not a constant expression
15 | constexpr volatile uint8_t* ptr=&PORTB;
which directly let me find reinterpret_cast<volatile uint8_t*>(37)' is not a constant expression. But also without any solution!
My target is very very simple: Write some class which can be configured to use a specific register like:
template < volatile uint8_t* REG>
class X
{
public:
X() { REG = 0x02; }
};
If we can not longer define pointer values as constexpr values, we can not use them in templates nor directly. This means, we only have run time variables, which can no longer be optimized and always needs space in ram and flash. This is not acceptable for very small embedded systems.
If that is really the fact, the only way to work is really using c-macros? I can't believe that none of my code will work anymore... and never will work in the future without using C macros.
I currently use avr-g++ (Fedora 10.2.0-1.fc33) 10.2.0 but it seems, that from all my readings it is correct behavior if used in C++17 mode.