Skip to content
This repository has been archived by the owner on Jan 7, 2019. It is now read-only.

avr-gcc version 7.2.0 (GCC) complains about dynamic initialization put into program memory area #314

Closed
strongly-typed opened this issue Nov 12, 2017 · 3 comments

Comments

@strongly-typed
Copy link
Member

Brew's current avr-gcc version complains about the actionList which should be placed into PROGMEM on AVR.

As far as I remember, it issued a warning in previous versions.

Compiling C++: /Users/usr/Dev/xpcc/build/unittest_atmega/xpcc/communication/sab/test/slave_test.o
In file included from ./xpcc/architecture/driver/accessor/flash_reader.hpp:60:0,
                 from ./xpcc/architecture/driver/accessor/flash.hpp:37,
                 from ./unittest/controller.hpp:35,
                 from ./unittest/harness.hpp:34,
                 from ./unittest/testsuite.hpp:34,
                 from xpcc/communication/sab/test/slave_test.hpp:31,
                 from xpcc/communication/sab/test/slave_test.cpp:31:
xpcc/communication/sab/test/slave_test.cpp: In member function 'virtual void SlaveTest::setUp()':
xpcc/communication/sab/test/slave_test.cpp:99:34: error: variable '{anonymous}::actionList' with dynamic initialization put into program memory area
  FLASH_STORAGE(xpcc::sab::Action actionList[]) =
                                  ^
./xpcc/architecture/driver/accessor/flash_reader_avr_impl.hpp:38:63: note: in definition of macro 'FLASH_STORAGE'
 #define FLASH_STORAGE(var)    extern const var PROGMEM; const var
                                                               ^~~

Any suggestions?

@chris-durand
Copy link
Member

The problem here is the reinterpret cast in the SAB__ACTION macro. An object with a PROGMEM attribute must be initialized by constant initialization (at compile time).

For constant initialization the standard requires that

each full-expression (including implicit conversions) that appears in the initializer of a reference
with static or thread storage duration is a constant expression (5.20).

(From section 3.6.2 Initialization of non-local variables, draft N4296)

Unfortunately, expressions containing reinterpret casts are explicitly excluded from being constant:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
[…]
(2.13) — a reinterpret_cast (5.2.10);
[…]

(from 5.20 Constant expressions)

@strongly-typed
Copy link
Member Author

That's a great in-depth explanation and thank you so much for going into that detail. Is there any practical solution to that problem?

@chris-durand
Copy link
Member

chris-durand commented Nov 21, 2017

This is the change in gcc that causes the compile error. I'm not very familiar with the gcc code but it looks like there is no easy way to avoid the error.

PROGMEM is a non-standardized gcc extensions but it seems it has the same semantics as constexpr. There is no way to initialize a constexpr variable from a reinterpret_cast expression (an equivalent C-style cast won't work either).

You will have to replace the reinterpret cast with a static cast. Currently the code casts all function pointers to a pointer to function taking a Response& and a const void * argument, regardless of the parameters the actually called function requires. This is not possible with static cast and is undefined behaviour anyway.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants