ISO/ IEC 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]