public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM
@ 2024-08-20 17:42 digger1984 at gmx dot com
  2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: digger1984 at gmx dot com @ 2024-08-20 17:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116433

            Bug ID: 116433
           Summary: [AVR] cannot place template class static members in
                    EEPROM
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: digger1984 at gmx dot com
  Target Milestone: ---

Created attachment 58963
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58963&action=edit
Complete sample code with three separate use cases

Context

I designed a template class in the hope it could make EEPROM storage somehow
transparent by implementing read and write accessors in a class/struct. The
desired goal is equivalent to this:

        eemem<initial_value> variable;
        foo(variable);

The compiler would then automatically fetch the value for the internal variable
before passing it to function `foo`.

Otherwise the conventional approach is:

        auto variable EEMEM = initial_value;
        foo(eeprom_read_<appropriate_b_w_d_idom>(&variable));

And so on for every similar situation. Same goes with writing but even more
verbose.

I'm using C++ ability to supply literals as template arguments. From there the
type is deduced from the argument. In order to achieve what I want(ed) I need a
static member variable to which I append the EEMEM macro for EEPROM storage.

For the reference I've used the same tactics for program memory storage and it
works as expected, therefore I hoped it would also work for EEPROM storage.

The problem

AVR-GCC version 13.2.0 ignores the section attribute and instead places static
members of template classes in RAM, which is not the desired effect. I've
looked up bugs #89148, #116184 and #87178 to find an explanation (I *think* I
understand the issue but I'm not quite sure).

Here's a minimal example to illustrate the problem:

        template <auto V>
        struct eemem
        {
                typedef type::remove_cv_t<decltype(V)> value_type;
                static value_type value __attribute__((section(".eeprom"),
used));
        };

        template<auto V>
        eemem<V>::value_type eemem<V>::value __attribute__((section(".eeprom"),
used)) = V;

        eemem<69U> test;

Note this is *not* the full class definition; I stripped it to the bare minimum
for illustration purposes. When accessed from function `main` like this:

        PORTB = eeprom_read_word(&test.value);

the compiled code appears as follows (also note there's no warning nor errors
at compile time):

        ba:     80 e0           ldi     r24, 0x00       ; 0
        bc:     91 e0           ldi     r25, 0x01       ; 1
        be:     0e 94 65 00     call    0xca    ; 0xca <eeprom_read_word>
        c2:     85 b9           out     PORTB, r24      ; 5

I'd understand if this bug is marked as a duplicate but I'd like to stress on
the fact that I'm not trying to move my variables into a section of my own,
only into what's been defined for the AVR platform as to EEPROM storage. So if
this is not possible, is there a workaround (e.g. with a custom linker script,
maybe)?

Attached is the complete test code I. Compiler command line options are:

        -Os -mmcu=atmega328p -std=gnu++20 -DF_CPU=16000000

Only the non-template class has its static member variable stored in EEPROM, as
expected. The other two have their member variable stored in RAM, which is
undesired.

Also note with AVR-GCC 14.1.0 (from Matt Godbolt Compiler Explorer) I get the
following error message:

        <source>:46:35: error: 'stg::t2::eemem::value' causes a section type
conflict with 'stg::t3::eemem<unsigned int>::value'

Best,
C.F.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-08-21  7:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-20 17:42 [Bug c++/116433] New: [AVR] cannot place template class static members in EEPROM digger1984 at gmx dot com
2024-08-20 17:46 ` [Bug target/116433] [AVR] cannot place template class static member variables " pinskia at gcc dot gnu.org
2024-08-20 17:55 ` digger1984 at gmx dot com
2024-08-20 21:41 ` gjl at gcc dot gnu.org
2024-08-21  7:57 ` digger1984 at gmx dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).