JTC1/SC22/WG21
N1258
Doc No. : WG21/N1258
Date : 6 September, 2000
Project : Programming Language C++
Author : Embedded C++ Technical Committee
Reply to: Seiji Hayashida
<seiji.hayashida@toshiba.co.jp>
ROM-ability (Performance Group)
1. Guide for Implementors
1.1 ROM-ability
ROM-ability is important for embedded programs whose code and data must
be stored in ROM.
Objects without const-qualifier can be modified.
Both ROM and RAM area must be allocated for such objects,
if they have constant initializer.
The definition of ROM-able object here is an object that needs only ROM
area.
The embedded programs whose memories are very tight require the compilers
to identify strictly ROM-able objects and allocate ROM area only for them.
1.2 ROM-able objects
The following objects should be ROM-able.
<User-defined objects>
o The objects which are const-qualified and initialized by constant
expressions. Examples:
- The aggregate (IS 8.5.1) object with static storage duration (IS 3.7.1)
whose initializers are all constants
[Example:
static const int tab[] = {1,2,3};
-- end example]
- Scalar type objects with external linkage
Although scalar type objects with internal linkage are ROM-able,
if they are not used for initialization or assignment
of pointer/reference variables, only values are used at the time
of compilation, i.e, object data areas are not allocated.
Therefore, it is not expected to allocate data area for
such objects even in ROM area.
[Note: Objects which are const-qualified and are not explicitly
declared to be extern have internal linkage(IS 7.1.5.1).]
[Example:
extern const int a = 1; // extern linkage
const int b = 1; // internal linkage
const int *c = &b; // variable b should be allocated
const int tbsize = 256; // it is expected that tbsize is not
// allocated at run-time
char ctb[tbsize];
-- end example]
o String literals
String literals are const-qualified array of char (IS 2.13.4), and so
they are ROM-able.
But when it is used as the initializer of a character array, and the
variable to be initialized is not a const-qualified array of char, it is
not ROM-able.
[Example:
const char *str1 = "abc"; // ROM-able
char str2[] = "abc"; // not ROM-able
-- end example]
<Compiler-generated objects>
o Virtual function table
If the virtual function of a class becomes static after linkage,
it is expected that the table is ROM-able.
o Jump table of switch statement
If a jump table is generated to implement switch statement, the table
is expected to be ROM-able.
o Type identification table
When a table is generated to identify RTTI types, the table is expected
to be ROM-able.
o Exception table
When exception handling is implemented by a static table, it is expected
that the table is ROM-able.
o reference to constants
If a constant expression is specified as the initializer for a
const-qualified reference, a temporary object is generated(IS
8.5.3).
This temporary object is expected to be allocated to ROM.
[Example:
const double & a = 2.0; // interpreted as follows
static const double tb = 2.0; // tb can be in ROM
const double & b = tb;
-- end example]
o initializers for aggregate objects with automatic storage duration
If all initializers for an aggregate object that has automatic
storage duration are constant expressions, a temporary object
that has the value of the constant expressions and a code that
copies the value of the temporary object to the aggregate object
may be generated.
This temporary object is expected to be allocated to ROM.
[Example:
void test() {
struct A {int a,b,c;};
A a = {1,2,3}; // may be interpreted as follows
static const A tb = {1,2,3}; // tb can be in ROM
A b = tb;
}
-- end example]
o constants generated during code generation
Some constants such as integer constants, floating point
constants and address constants may not be the part of
instruction code but the data. These data are stored in memory
and loaded when they are used.
They are expected to be allocated to ROM.
[Example:
void test() {
double a;
a += 1.0; // may be interpreted as follows
static const double t = 1.0; // t can be in ROM
const double *tp = &t;
a += *tp;
}
-- end example]
1.3 Constructor and ROM-able objects
Even though constant expressions are specified as the
initializers for all the members of const qualified class object
that has user-declared constructors(IS 12.1), the initialization
will be done dynamically in general.
But in this case, because the initialization can be done
statically by analyzing constructors, the optimization so as to
allocate the class object to ROM is expected to be
implemented.
[Example:
class A {
public:
int a;
A(int v) : a(v) { }
};
const A tab[2] = {1,2};
-- end example]
2. Guide for Users
Even though constant expressions are specified as the
initializers for all the members of const qualified class object
that has constructors, the initialization will be done
dynamically in general.
Note that such class object may not be expected to ROM.
[Example:
class A {
public:
int a;
A(int v) : a(v) { }
};
const A tab[2] = {1,2}; // A(int) may be used for initialization
-- end example]
A class object which has private member, destructor, base class
or virtual function should not be initialized statically (IS 8.5.1).
Also, a class object which has non-POD type members will be
initialized dynamically (IS 12.6.1).
[Example:
class complex {
// ...
public:
complex(double);
// ...
};
class X {
public:
int i;
complex c;
};
const X x = {99,77.7}; // complex(double) is applied for X.c
-- end example]