Does C++ standard require objects to be allocated in continuousmemory?

G

google

Hello,

in embedded programming, different kinds of memory exist, e.g. RAM and
ROM (Flash memory). For a class containing variables and constant
values one might want to put the variables in RAM and the constants in
ROM, which means that the object is split into different parts in
memory.

Besides from the fact that the current compiler does not support such
feature: does the C++ standard require an that the objects data
resides in continuous memory (e.g. starting from this pointer), or can
the object be put in different places in memory?

Thanks,

Uli
 
J

James Kanze

in embedded programming, different kinds of memory exist, e.g.
RAM and ROM (Flash memory). For a class containing variables
and constant values one might want to put the variables in RAM
and the constants in ROM, which means that the object is split
into different parts in memory.

Besides from the fact that the current compiler does not
support such feature: does the C++ standard require an that
the objects data resides in continuous memory (e.g. starting
from this pointer), or can the object be put in different
places in memory?

It depends. If the constants are static members, they can be
anywhere. (If they're not, they won't be constant until after
the constructor has finished running, so obviously they can't be
put into ROM. In addition to the issue Victor pointed out.)
 
U

Uli

It depends.  If the constants are static members, they can be
anywhere.  (If they're not, they won't be constant until after
the constructor has finished running, so obviously they can't be
put into ROM.  In addition to the issue Victor pointed out.)

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Hi,

I am not concerned about the static members, my question is about non-
static ones. As far as I understand it, an object can be put in ROM if
it is rom-able (see the restrictions in the PDTR18015 "Technical
Report on C++ Performance"). However, since it must be in continuous
memory, this means it is either completely in ROM (making it constant
from compile/link time) or completely in RAM (wasting costly RAM on
constant values).

However, this is specific embedded domain problem....

Regards, Uli
 
U

Uli

The constants would be defined as statically scoped. In which case they will be stored once rather than per instance. Marking them as const would futher allow the compiler / linker to optimize their placement into read only storage.
MS Visual C++ supports this right now. non static class data is placed on the heap, contiguously, static data is placed in the EXE image in a section that, when mapped into memory, will be R-only or RW as appropriate. Im sure other current c++ dev environments do similar things.

Hi,

to be precise, my concern is about non-static constants that are
different for each object instance.

Regards, Uli
 
E

Erik Wikström

Hi,

I am not concerned about the static members, my question is about non-
static ones. As far as I understand it, an object can be put in ROM if
it is rom-able (see the restrictions in the PDTR18015 "Technical
Report on C++ Performance"). However, since it must be in continuous
memory, this means it is either completely in ROM (making it constant
from compile/link time) or completely in RAM (wasting costly RAM on
constant values).

Well, as pointed out it is only static members that can be truly
constant. A const member in a class can have different values in each
object of that class since the value is defined when the object is
created. In other words you would not waste RAM on truly constant
values, and if they are truly constant you can make them static.
 
E

Erik Wikström

Hi,

to be precise, my concern is about non-static constants that are
different for each object instance.

They can obviously not be in ROM since you then would be unable to
assign the value to the const member in the first place. Unless you can
make the whole instance static const (as described in PDTR18015).
 
J

James Kanze

Well, as pointed out it is only static members that can be
truly constant. A const member in a class can have different
values in each object of that class since the value is defined
when the object is created. In other words you would not waste
RAM on truly constant values, and if they are truly constant
you can make them static.

Yes and no. A good compiler should be able to put something
like:
std::complex< double > const i( 0.0, -1.0 ) ;
in ROM (provided that the constructor is inline). I just can't
conceive of a case where it would make sense to have an object
where half of the object is non-static const, and the other half
not. I don't really know anything about Uli's application, so
that doesn't mean much, but it did make me wonder if he didn't
have static members in mind.
 
B

Bo Schwarzstein

Hello,

in embedded programming, different kinds of memory exist, e.g. RAM and
ROM (Flash memory). For a class containing variables and constant
values one might want to put the variables in RAM and the constants in
ROM, which means that the object is split into different parts in
memory.

Besides from the fact that the current compiler does not support such
feature: does the C++ standard require an that the objects data
resides in continuous memory (e.g. starting from this pointer), or can
the object be put in different places in memory?

Thanks,

Uli

Why not have a look at "Inside C++ Object Model" from Stan Lippman, it
shows very clear about this kinds of question, but I think we should
notice that different compilers maybe have different implementions.
 
J

Jerry Coffin

Hello,

in embedded programming, different kinds of memory exist, e.g. RAM and
ROM (Flash memory). For a class containing variables and constant
values one might want to put the variables in RAM and the constants in
ROM, which means that the object is split into different parts in
memory.

Besides from the fact that the current compiler does not support such
feature: does the C++ standard require an that the objects data
resides in continuous memory (e.g. starting from this pointer), or can
the object be put in different places in memory?

It has to start from the "this" pointer -- but it can have arbitrary
padding between members, and members can be rearranged anywhere you have
an access specifier. I doubt it's what the committee had in mind, but I
don't see anything saying that what's "padding" for one object can't
also be "storage" for another object. IOW, if you started with something
like:

class X {
int x;
public:
static const int y = 10;
};

I think the compiler is free to arrange things so 'x' is in RAM, then
the rest of the RAM address space (and possibly part of the ROM address
space) is "padding", and y is somewhere in ROM. Thanks to the access
specifier between the two, it's also legal for the compiler to rearrange
'y' so it precedes 'x', if the ROM happens to be at lower addresses than
the RAM.

In theory there's nothing to prevent the same strategy if you have data
that's constant per instance -- but I find it harder to believe that any
compiler will really do it. e.g.:

class Y {
int a;
private:
const int b;
public:
Y(int init) : b(init) {}
};

int main() {
Y y[2] = { Y(0), Y(1) };
}

In theory, the '0' and '1' could be somewhere in ROM, and there's some
arbitrary amount of "padding" between 'a' and 'b' so 'a' is in RAM while
'b' is in ROM (and what's treated as padding for this purpose, also
happens to be used to store other values).
 
I

Ian Collins

Jerry said:
It has to start from the "this" pointer -- but it can have arbitrary
padding between members, and members can be rearranged anywhere you have
an access specifier. I doubt it's what the committee had in mind, but I
don't see anything saying that what's "padding" for one object can't
also be "storage" for another object. IOW, if you started with something
like:

class X {
int x;
public:
static const int y = 10;
};

I think the compiler is free to arrange things so 'x' is in RAM, then
the rest of the RAM address space (and possibly part of the ROM address
space) is "padding", and y is somewhere in ROM. Thanks to the access
specifier between the two, it's also legal for the compiler to rearrange
'y' so it precedes 'x', if the ROM happens to be at lower addresses than
the RAM.
The access specifier has nothing to do with layout in this case. The
static member is unique across all instances of X and is accessible
before any instances of X are instantiated; so it can't be in stored in
the memory allocated for an instance of X.
 
J

Jerry Coffin

[ ... ]
The access specifier has nothing to do with layout in this case. The
static member is unique across all instances of X and is accessible
before any instances of X are instantiated; so it can't be in stored in
the memory allocated for an instance of X.

Quite true -- I obviously wasn't thinking clearly when I wrote that.
 
P

PeterAPIIT

What is the conclusion of this discussion ?

As far as i know, static const member will be placed in ROM while
const member still placed in RAM.


Static member is instantiated before object is instantiated.
Therefore, memory for both value is not same.

Am i correct, please correct me if i wrong.

Thanks.
 
I

Ian Collins

What is the conclusion of this discussion ?

As far as i know, static const member will be placed in ROM while
const member still placed in RAM.
A static const member can be placed in ROM, if the compiler has that
option. A const member is unique to and part of each instance of the
class. Unless the class instance is statically initialised, the value
of a const member is not known at compile time.
Static member is instantiated before object is instantiated.
Therefore, memory for both value is not same.
Correct.
 
K

kwikius

What is the conclusion of this discussion ?

As far as i know, static const member will be placed in ROM while
const member still placed in RAM.


Static member is instantiated before object is instantiated.
Therefore, memory for both value is not same.

Am i correct, please correct me if i wrong.

Thanks.

AFAIK you have to break this down further.

static const I , where I is an integral type {bool, int, long etc),
whether in class or function is a compile time value and *usually* uses
no memory at runtime. In practise when such value is accessed the value
is probably part of the low level opcode, essentially ROM but part of
code rather than data section.

static const T where T is any other type {double, UDT etc} is treated
differently and *will* have an address in RAM.

You can tell the difference because if you do not have a definition of
second type linked in you will get linker errors.

OTOH ... For first (Integral constant type} *If* you do something that
uses its address then suddenly it changes and you must now provide a
definition for the linker and then it will be placed in RAM.

Yep.. its complicated. In reality static const I is a separate entity
neither type nor object, however AFAIK this realisation of static const
integral type emerged fairly recently and it is somewhat of a grey area
for compilers, as to what actually constitutes using its address. One
solution to this problem is to clearly delineate which types are
designed as static integral constants and which are not and use special
methods for access ( e.g Boost MPL wraps each constant in a template
type and then works on types leaving details of how to prevent linkage
issues hidden}

regards
Andy Little
 
I

Ian Collins

kwikius said:
AFAIK you have to break this down further.

static const I , where I is an integral type {bool, int, long etc),
whether in class or function is a compile time value and *usually* uses
no memory at runtime. In practise when such value is accessed the value
is probably part of the low level opcode, essentially ROM but part of
code rather than data section.

static const T where T is any other type {double, UDT etc} is treated
differently and *will* have an address in RAM.

You can tell the difference because if you do not have a definition of
second type linked in you will get linker errors.

OTOH ... For first (Integral constant type} *If* you do something that
uses its address then suddenly it changes and you must now provide a
definition for the linker and then it will be placed in RAM.
No, the compiler can place it where it likes, there isn't a standardised
location for constant data. There's no reason why a static const
integral type member defined outside of the class body can't be placed
in ROM.
 
K

kwikius

No, the compiler can place it where it likes, there isn't a standardised
location for constant data.  There's no reason why a static const
integral type member defined outside of the class body can't be placed
in ROM.

I guess so. The only use I have had for blowing in ROM is lookup
tables. For individual values I would hope the compiler stores them in
immediate opcodes and not data memory of any kind.

and of course ROM is somewhat painful if you want to adjust the config
at runtime!

regards
Andy Little
 
J

James Kanze

I guess so. The only use I have had for blowing in ROM is
lookup tables. For individual values I would hope the compiler
stores them in immediate opcodes and not data memory of any
kind.

It can do that as well. It can more or less put the variable
where ever it wants (including in ROM), but it doesn't have to
access it, as long as the observable behavior of the program
doesn't change (and if it never accesses the variable, it might
not put it anywhere).
and of course ROM is somewhat painful if you want to adjust
the config at runtime!

But then, you wouldn't declare it const.
 
K

kwikius

Ah .. should have been placed in *memory*. Whether ROM or RAM is pretty
much irrelevant, but only if its address is used , which IMO is poor
style anyway.
It can do that as well. It can more or less put the variable
where ever it wants (including in ROM), but it doesn't have to
access it, as long as the observable behavior of the program
doesn't change (and if it never accesses the variable, it might
not put it anywhere).


But then, you wouldn't declare it const.

Well you couldnt declare it static const. I found blowing constants in
ROM painful during development. Its far better to have constants
configurable... it gives users something to tinker with too :)

regards
Andy Little


regards
Andy Little
 
A

Andrew Koenig

Yes, it requires that objects occupy a contiguous memory portion. That's
how an object is defined.

Not quite. Consider:

struct A { int a; };
struct B: virtual A { int b; };
struct C: virtual A { int c; };
struct D: virtual A { int d; };
struct E: B, C, D { };

Every object of type E includes objects of types B, C, and D among its
base-class parts. Those objects, in turn, share a common sub-object of type
A. Therefore, if we have an object of type E, at least one of the B, C, or
D objects must occupy noncontiguous memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top