This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Text resources and linker optimization

Hi there!

At present I am writing a program in C51 that might be available in different language versions one day. So I place all texts in one file called texts.h.

That file looks like
[...]

#define    OK_STR     "ok"
#define    CRLF_STR   "\x0D\x0a"

#define    MODEM_STR  "Modem"
[...]

Many of those strings are used several times in different C source files. Now my question... will those strings be located in one address in the code memory or will they be located once per module where they are used or will they be located for every time I use them?

I guess, I could make sure that a string only occures once in the code by creating constants in code space in a texts.c and make them public as global constants in texts.h. But that would be the harder way, since I have to type that string constant name at least three times (texts.c, texts.h and where I use them).

So, how does the linker optimize the string constants?

  • Using a #define affects the output of the preprocessor. As far as the compiler in concerned, it just sees lots of literal strings with no immediately obvious connection between them.

    While it might theoretically be possible for an optimiser to pick up on the fact that one string is being used several times, I am pretty sure that C51 does not do this.

    Your best bet is to define constants stored in code memory, it is a little bit more trouble (but not much) and the program memory savings are potentially significant.

  • I presume what you're looking for is an equivalent of Borland's "Merge Duplicate Strings" option?

    AFAIK, Keil does not have an equivalent option; ie, every time you write a string literal it will occupy a separate area of code memory.

    Therefore, you will have to adopt your texts.c + texts.h approach:

    But that would be the harder way, since I have to type that string constant name at least three times (texts.c, texts.h and where I use them).

    But using your original #define approach would still require typing the names where you define them and where you use them; it's not really that much extra effort, is it?
    And the texts.h file could very easily be created by simply editing your texts.c file, and removing the initialisations.
    In fact, if you're that worried, you could write a macro which allow you to just type once and serve both purposes!

  • Why don't you try it yourself? It should not be too difficult.
    I am using C166 toolset and I remember an occasion when compiler (or linker) merged identical strings in my program. I noticed that because the program modified them (everything was in RAM) and after modification of one of the strings I could see the other one modified as well.
    I can't say if it was linker or compiler (common tail merging) optimization because everything was happening inside one module.
    So there may still be hope.
    Regards.
    Mike.