2024-07-01 11:04 AM
Hello,
According to the manual , "This attribute, attached to a variable with static storage, means that the variable must be emitted even if it appears that the variable is not referenced."
In the following code, unreferenced_variable is always discarded:
static uint8_t unreferenced_variable __attribute__((used));
There's no warning from the compiler.
Solved! Go to Solution.
2024-07-09 03:56 AM
> 'used' attribute Appears Ineffective.
But it's not ineffective. It works as intended. You're compiling with -fdata-sections and --gc-sections, so you're explicitly asking for the variable to be pruned. You can't blame the toolchain for doing exactly what you're asking it to do, and you can't call the attribute ineffective because of it.
> In addition, if the same source (with 'used' attributes) was ported to a toolchain that did support 'used'
> (e.g. TI arm clang) it would not need further linker instructions.
This would surprise me. Have you really tested this claim against TI's compiler (with the same options compiler/linker)?
Because from what I understand, other compilers would behave in the same way. i.e. specifying --gc-sections explicitly asks the linker to ignore the used attribute. If the `retain` attribute is not available, manually adding a carve-out in the linker script is probably the best you'll get.
It's also possible (untested) that you could get what you want by using the `section` attribute instead.
If you manually place the variable in a section that contains any other used variables, it should not get pruned.
Also, the use case you gave earlier was that of a version string kept a fixed memory location in a bootloader. But there would be no need to make the variable static in that case (in fact, exporting it as a symbol would be good documentation), and you could not get it to be at a known fixed location with manually manipulating the linker script, anyway.
2024-07-09 06:56 AM
We'll have to agree to disagree.
I'm asking the toolchain to keep the variable irrespective of optimization by marking it in source code for special handling. Other compilers have set a precedent for being able to do just that but this particular toolchain does not do what I'm asking.
The same 'used' attribute does exactly what I'm asking in at at least one other compiler (TI arm clang) without jumping through further hoops.
2.7.3. Variable Attributes — TI Arm Clang Compiler Tools User's Guide
This is confirmed by my extensive use of this toolchain in other projects. It's not just a "claim".
It's possible that the problem here (with GCC) is that 'retain' is not supported. If 'retain' is required to stop the linker pruning then 'used' may as well not be supported either. I think that without 'retain', 'used' is like a bike with one wheel. The single wheel works perfectly well but the bike is useless as a bike.
In other words, 'used' is ineffective.
2024-07-09 07:42 AM - edited 2024-07-09 07:43 AM
Anything that you write in the C source is seen by the compiler. So you want the compiler to leave a message to the linker (in the object file) not to discard this data item. The linker obviously should understand this message. New clang based toolchains have many cool features, they may do this one too. Same about proprietary toolchains (IAR, Keil...) - they can do any proprietary tricks to help their sales. Now imagine what the GCC (opensource) maintainers would do? They would say - the ld already has KEEP exactly for this purpose; just add KEEP for your custom section name in your link script and call this a bike )) Adding a special attribute "retain" (backporting from clang?) to produce these special section names is just a syntactic sugar.
2024-07-09 08:28 AM - edited 2024-07-09 08:29 AM
> This is confirmed by my extensive use of this toolchain in other projects. It's not just a "claim".
I believe you, and looked at the reference you provided. It does seem like the semantics of `used` is simply different for the ST vs. TI toolchains. (pavel did warn us about vendor-specific extensions early on...)
Here's another possible solution for GCC:
--gc-keep-exported
When --gc-sections is enabled, this option prevents garbage
collection of unused input sections that contain global
symbols having default or protected visibility. This option
is intended to be used for executables where unreferenced
sections would otherwise be garbage collected regardless of
the external visibility of contained symbols. Note that this
option has no effect when linking shared objects since it is
already the default behaviour. This option is only supported
for ELF format targets.
So, you still haven't explained why a variable that you expect someone/something to access someday needs to be static. What would the disadvantage be in exporting the symbol? in a bootloader it's meaningless, in an shlib it makes sense, and if it's an easter-egg for some venutian invader reverse-engineering the firmware for your gadget in the year 2099, it's harmless.
as for whether "ineffective" is the proper term, we do disagree (but I, also, agree to).