Skip to main content
CTabo.1
Senior
September 14, 2023
Solved

How to retain unsed constant variables

Hello,
I define following constant string, indicating the program version.

static const char version_s[] __attribute__((used)) = "V.10";

This string isn't used in other part of code, but is only defined with the purpose to put in the binary file, a string easy to find, and to make the CRC over the code, depending from the program version.

However, I see that the version string is not included in the binary file, and consequently CRC doesn't depend on it.

Where is the mistake?

Thank you,
Carlo.

    This topic has been closed for replies.
    Pavel A.
    Pavel A.Best answer
    September 14, 2023

    As @Tesla DeLorean wrote - linkers do removal of unused code. Attribute(used) affects only the compiler, you need something else for the linker. For the GNU linker use a custom section with KEEP in the linker script. For IAR, use specifier __root.

    6 replies

    TDK
    September 14, 2023

    If you use the string to calculate a CRC, it'll be included in the binary. How do you know it's not included? When you calculate the CRC, what data is it using? Perhaps show the relevant code.

     

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    CTabo.1
    CTabo.1Author
    Senior
    September 14, 2023

    Hello,
    I tried to modify the constant string value, but the CRC didn't changed.
    So I tried to search the "V.10" string in the .elf file, using a binary editor, and I wasn't able to find it.

    TDK
    September 14, 2023

    It sounds more like a program bug than a compiler/linker issue. If you're using the string in the program, the compiler has to include it. It can't optimize it out since it doesn't know how the CRC functions, and all CRC accesses are volatile.

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Tesla DeLorean
    Guru
    September 14, 2023

    If you don't reference things internally the linker is apt to apply dead code removal to discard things.

    Check .MAP files for the symbol, and perhaps refer to it or use the KEEP() directive in the Linker Script

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Pavel A.
    Pavel A.Best answer
    September 14, 2023

    As @Tesla DeLorean wrote - linkers do removal of unused code. Attribute(used) affects only the compiler, you need something else for the linker. For the GNU linker use a custom section with KEEP in the linker script. For IAR, use specifier __root.

    CTabo.1
    CTabo.1Author
    Senior
    September 15, 2023

    Thank you @Tesla DeLorean  and @Pavel A. 

    I modified the linker script, adding the new section .ver, with the KEEP directive

    .ver :
    {
    . = ALIGN(4);
    KEEP(*(.ver))
    . = ALIGN(4);
    } >VER

    Then I have allocated my constant version string in the new .ver section:

    static const char version_s[VERSION_STRING_LEN] __attribute__((section(".ver"), used)) = "V.1";

    And now, when I modifiy the version_s[] value, the CRC changes too.

     

    Moreover, I have seen that it works also without specifing the used attribute:

    static const char version_s[VERSION_STRING_LEN] __attribute__((section(".ver"))) = "V.1";

    In this last case, however, I have the following warning:

    warning: 'version_s' defined but not used [-Wunused-const-variable=]

    So I prefer to specify also the used attribute.

     

    Thank you,

    Carlo