1

I have following class:

class Bit
{
    void * bb_addr;

    public:
        constexpr Bit ( void * __data, int bitpos )
            : bb_addr((void*)(0x22000000 + ((uint32_t)(__data) - 0x20000000) * 32 + bitpos * 4))
            {}
};

In this class definition I used constexpr constructor - simply I want to create object at compile time. This is requirement, because I write for microcontrollers, I have quite lot of program code memory, but not much of RAM. Expression in constructor is calculation of bit-band address for specified bit - I would like to use this functionality on microcontroller. In another place objects of this class are defined with static constexpr modifier such as static constexpr Bit(&somevar, 15); so finally it was constant object in FLASH memory. This is my target.

Unfortunately, this is rejected by compiler due to non constant expression. This make me consider - it is possible to use this kind of expression, in C++ 17 with leaving whole initializer constexpr?

I'll try various options - passing by templated constructor, or reference to __data - no way.

G++ says that casting from integer to pointer is not a constant expression. Ok, I know. But pointer arithmetic don't allow multiply, so even casting to unsigned char* don't solve the problem.

So my question is: It is possible to calculate complex address in compile time in C++? According to bit-band address calculation of Cortex-M3 cores? It seems impossible in C++17 standard, but maybe someone know's the solution ( even only G++-accepted )

Szymon
  • 21
  • 3
  • What about storing `bb_addr` as an integer, and only cast it to pointer when needed? – Ranoiaetep Mar 28 '22 at 19:28
  • 1
    what `somevar` is? if it is a run time variable, how could be possible to calculate some kind of compile time address for that? See also here https://stackoverflow.com/questions/38412849/why-can-function-pointers-be-constexpr/38413329#38413329 – Federico Mar 28 '22 at 19:31
  • @Federico - `somevar` is global variable - in .bss section. But your answer give me more knowledge. @Ranoiaetep - This will be good idea, but `error: conversion from pointer type 'void*' to arithmetic type 'uint32_t' {aka 'long unsigned int'} in a constant expression|` - pointer to arithmetic conversion ... :/ – Szymon Mar 28 '22 at 19:54
  • 3
    You cannot do this even with only gcc. Even if `somevar` is a global variable, its address is not known by the compiler, but will be assigned by the linker later, so there is nothing for the compiler to perform calculations on. – Fatih BAKIR Mar 28 '22 at 20:42
  • why do you use `(uint32_t)(__data)` instead of `(uintptr_t)__data`? Also the use of `__` in user code is prohibited. See [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/q/228783/995714) – phuclv Apr 08 '22 at 04:19

0 Answers0