reinterpret_cast is not a constant expression - needed help to find solution
Zygmunt Ptak
zygmuntptak@gmail.com
Mon Oct 2 21:57:00 GMT 2017
Hi Jens,
This helps just a little.
I figure out that I can use something like:
template<typename RegType, intptr_t ptr>
class Register {
RegType & reg() { return *reinterpret_cast<RegType*>(ptr); }
};
and then, here is important:
I have to use this:
const intptr_t reg_value_b = reinterpret_cast<intptr_t>(&PORTB);
typedef Register<volatile uint8_t, reg_value_b> RegisterPortB;
instead of this:
typedef Register<volatile uint8_t, reinterpret_cast<intptr_t>(&PORTB)>
RegisterPortB;
// second case will tell you that reinterpret_cast is not constexpr.
Overall in my case non-constexpr for reinterpret_cast sucks. I'm
taking few more bytes in final binary (just for very simple code).
If I will use in every part of my code there can be a case when I will
not have enough memory.
Would be great to disable that somehow in gcc. For now I'm not able
change my code.
Best Regards
Zygmunt
2017-09-05 11:52 GMT+02:00 Kilian, Jens <jens.kilian@advantest.com>:
> Hi Zygmunt,
> You could try changing the second template parameter to an actual pointer (the register address before casting) and apply the reinterpret cast to it in the reg() function.
>
> Hope this helps,
>
> Jens.
>
>> -----Original Message-----
>> From: Zygmunt Ptak [mailto:zygmuntptak@gmail.com]
>> Sent: Sunday, 03 September, 2017 22:20
>> To: gcc-help@gcc.gnu.org
>> Subject: reinterpret_cast is not a constant expression - needed help to
>> find solution
>>
>> Hi,
>>
>> I have a code for AVR written in c++.
>> To get the same size result as C code I'm using template classes.
>> For example:
>>
>> #define AVR_REG_TO_U16(REG) (reinterpret_cast<u16>(& REG))
>>
>> template<typename RegType, u16 reg_r>
>> struct Register
>> {
>> typedef Register<RegType, reg_r> Type;
>> constexpr Register<RegType, reg_r>() {}
>> static RegType & reg() { return *reinterpret_cast<RegType*>(reg_r); }
>> void operator = (RegType value) { reg() = value; }
>> void setBit(RegType value) { reg() = static_cast<RegType>(reg()
>> | 1 << value); }
>> void dropBit(RegType value) { reg() = static_cast<RegType>(reg()
>> & ~(1 << value)); }
>> void clear() { reg() = 0; }
>> void setBits(RegType mask) { reg() = static_cast<RegType>(reg()
>> | mask); }
>> void clearBits(RegType mask) { reg() = static_cast<RegType>(reg()
>> & ~mask); }
>> operator RegType() { return reg(); }
>> } __attribute__((packed));
>>
>> // and finally:
>>
>> Register<volatile uint8_t, AVR_REG_TO_U16(PIND)> pin_d;
>> pin_d.setBit(1);
>>
>> Everything works pretty cool on old compiler.
>> But on newer (in my case gcc-7.1.0) there is an error:
>>
>> error: 'reinterpret_cast<volatile uint8_t* {aka volatile unsigned
>> char*}>(41)' is not a constant expression
>>
>> I tried found some solution, but nothing.
>> All the time the same problem.
>> Is it possible to turn off that option?
>>
>> I understand that this type of the code doesn't make a sens on PC, but
>> on AVR it really does.
>>
>> Of course that simple example looks like not having any benefit.
>> But it has, compiler nicely optimize code and as I said I'm able to
>> get the same size of the code like in pure C.
>> Size is really matter here with 2kB of the SRAM on atmega328p.
>> I don't want to use pure C. I want to use C++ which is better for my
>> project.
>>
>> Best regards
>> Zygmunt Ptak
More information about the Gcc-help
mailing list