On 03/05/2012 15:29, Gabriel Dos Reis wrote:
On Thu, May 3, 2012 at 3:33 AM, Georg-Johann Lay<a...@gjlay.de>  wrote:
Gabriel Dos Reis schrieb:

Georg-Johann Lay wrote:

Gabriel Dos Reis wrote:


I guess I would need to get my feet wet with
1. minimal free-standing  C++ implementations without exceptions
2. get support for RTTI (without exceptions)
3. exceptions (assuming 1 and 2 are done successfully)

Regarding 2., I would like to understand the general policy:  RTTI data
are
generally const and should be best stored in read only location.  What
is
the general preference for AVR?  Put read only data in program memory or
data segment?  Apologies for the triviality but the recent discussion
about
__func__ got me thinking.


The preferred place is program memory, i.e. flash, i.e. something like
.progmem section.

Read-only data is located in .rodata which is located in RAM.

This is because const qualifier is not enough to put data in flash,
just assume:

char bar (const char *p)
{
  return *p;
}

char foo (char *p)
{
  char c = bar (p);
  *p = 0;
  return c;
}

bar() must not read from flash.


Yes, "const" qualifier on *parameters* is not enough.
However "const" qualifier on *objects* should be enough.
(and for C++, we now have "constexpr" to statically
guarantee that)


That's not enough.

The reason is that it's completely legal in C to access a
non-const object through a const-qualified pointer as
lined out in bar being called by foo above.

I think this is okay for C++, too?

In C++, you can also access a non-const object with
a const qualified pointer.  But, that is not what I was
suggesting.  I am suggesting that a const(expr) *object* should
go in program memory because it cannot be modified.  The
only requirement is that it is statically initialized (e.g. at most
at link time.)

The only time one can't put a const object in program memory
is when it requires a dynamic initialization. Constexpr objects
do not require dynamic initialization; the same is true for
statically initialized const object.


The trouble here is that the AVR uses different instructions to read from program memory and from data (ram + peripherals) space. It is legal to write code like this:

int x;                  // Must go in ram
const int * p = &x;
int foo(void) {
        return *p;
}

Thus when the compiler generates code for reading "*p", it must generate the "read from ram" instructions.

If the first line is changed to "const int x = 10;", then x must still be put in ram, even though it never changes, because otherwise foo() would fail.

So on the AVR, constant data is forced into ram because of the instructions used to access it, not because it might change.

If the new memory spaces can be used to avoid this, then that's great. The ideal is that the constant data gets put into a __flash memory space, which would be the most efficient. An alternative might be to use the general memory space, which would allow some constant data to go in flash and other bits to go in ram, at the cost of using 24-bit pointers. But I don't know enough about this to know if what is possible or desirable here.

mvh.,

David

_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to