This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

allocating constant in memory

Hello,

I'm using CCS  Version: 6.1.0.00104, TIRTOS: tirtos_tivac_2_14_04_31 with TM4C129.

i have many number of constants that i used inside my functions like

function1("hello");

function2("hello");

i was expecting that the compiler is allocating the hello constant in the same memory location, but unfortunately, i can see the first hello in different location than the second hello.

Is it something which is related to the optimization?

Thanks,

Mohammed Fawzy

  • Mohammed Fawzy said:
    Is it something which is related to the optimization?

    You didn't say if you are using the TI or GNU ARM compiler, so I had a look using TI ARM compiler v5.2.6.

    The ARM Optimizing C/C++ Compiler User's Guide doesn't specify how common string constants are combined, so a test program was created. The results show that:

    a) With the Optimization Level set in the range from Off to Interprocedure Optimizations common string constants used in the same compilation unit are only stored once, but the same constant used in multiple compilations unit have one copy of the string constant per compilation unit.

    b) With the Optimization Level set to Whole Program Optimizations a single common string constant is used for all compilation units.

    The test was a simple bare-metal example with only two compilation units using common string constants, but hopefully the Whole Program Optimization should combine common string constants across many compilation units for a TI-RTOS program.

    The test program is attached 0284.TM4C123_TI_string_constants.zip 

    Edit: Attach a better example in which the same constant string is used in different functions within one compilation unit, this didn't change the results.

  • Also consider that the programmer has control:
    extern const char hello_string[];
    function1(hello_string);
    function2(hello_string);
    and then in some source file define that global object:
    const char hello_string[] = "hello";
    This guarantees that the storage is shared, for any standard-conforming C implementation.
  • Actually, i tried to compile using "Whole Program Optimizations" option but something wrong went with the compiler, please check the attached picture.

  • thanks for the suggestion, but it won't help me as it will cause coupling between the modules.
  • That shouldn't happen.  Sorry.  To pursue this problem, we need a test case which allows us to reproduce it.  In this case, that means your whole project.  I'd appreciate if you would package it up and attach it to your next post.

    Thanks and regards,

    -George

  • Hi Mohammed,

    Initially I though the previous answer using a variable was what you might be looking for but it sounds like you need string literals to take the same memory location but still keep the source files decoupled.

    After a few searches myself on the web I found the following which may help everyone understand what may be going on and if there is a solution.


    http://stackoverflow.com/questions/11399682/c-optimisation-of-string-literals

    Apparently, this is called "string pooling".  From the link above, "...It's optional in Microsoft Compilers, but not in GCC. If you switch off string pooling in MSVC, then the "same" strings in the different arrays would be duplicated, and have different memory addresses, and so would take up an extra (unnecessary) 50 or so bytes of your static data.

    EDIT: gcc does in fact have an option, -fwritable-strings which disables string pooling. The effect of this option is twofold: It allows string literals to be overwritten, and disables string pooling. So, in your code, setting this flag would allow the somewhat dangerous code

    /* Overwrite the first string in a, so that it reads 'xne'.  Does not */ 
    /* affect the instances of the string "one" in b or d */
    *a[0] = 'x';
    "

    http://programmers.stackexchange.com/questions/294748/why-are-c-string-literals-read-only

    Current C compilers are able to optimize and have "ions" and "expressions" share their last 5 bytes (including the terminating null byte).

    Try to compile your C code in file foo.c with gcc -O -fverbose-asm -S foo.c and look inside the generated assembler file foo.s by GCC

    At last, the semantics of C is complex enough (read more about CompCert & Frama-C which are trying to capture it) and adding writable constant literal strings would make it even more arcane while making programs weaker and even less secure (and with less defined behavior), so it is very unlikely that future C standards would accept writable literal strings. Perhaps on the contrary they would make them const char[] arrays as they morally should be.

    Notice also that for many reasons, mutable data is harder to handle by the computer (cache coherency), to code for, to understand by the developer, than constant data. So it preferable to have most of your data (and notably literal strings) stay immutable. Read more about functional programming paradigm.


    It looks like you should be able to try the second idea if the compiler is similar to gcc and the gnu toolset.  If not, only you as the developer can make the decision whether or not the decoupling each of these string literals in the source code is higher priority than using immutable string literals in the executable preferred by the author of the second section above.

  • The compiler does not presently have the ability to do "perfect" string constant sharing, because it does not know at compile time whether function will end up being used in the application or not. There are mechanisms to accomplish this, but the TI compiler does not support them. The TI compiler will try to share string constants to some degree, but must make some conservative assumptions to preserve program correctness. If you have an example where you think the compiler should be able to figure it out, please do show us the test case, as George indicates.