Any data elements that are read-only should be moved into the text segment. This can be achieved using const declarations. For example, the following character string will reside in the .data section, which is part of the writable data segment:
char * rdstr = "this is a read-only string"; |
whereas, the following character string will reside in the .rodata section, which is the read-only data section contained within the text segment:
const char * rdstr = "this is a read-only string"; |
Although reducing the data segment by moving read-only elements into the text segment is an admirable goal, moving data elements that require relocations can be counter productive. For example, given the array of strings:
char * rdstrs[] = { "this is a read-only string", "this is another read-only string" }; |
it might at first seem that a better definition is:
const char * const rdstrs[] = { ..... }; |
thereby insuring that the strings and the array of pointers to these strings are placed in a .rodata section. The problem with this definition is that even though the user perceives the array of addresses as read-only, these addresses must be relocated at runtime. This definition will therefore result in the creation of text relocations. This definition is best represented as:
const char * rdstrs[] = { ..... }; |
so that the array strings are maintained in the read-only text segment, but the array pointers are maintained in the writable data segment where they can be safely relocated.
Some compilers, when generating position-independent code, can detect read-only assignments that will result in runtime relocations, and will arrange for placing such items in writable segments (for example .picdata).