Preventing gcc from discarding a variable just because it is not used - gcc

Normally I compile with flags that discard all variables that are never used (using -fdata-sections). But sometimes, I need to include a variable into a special section and I want that variable to never be optimized away even if it is not used.
How can I tell gcc linker (using attributes perhaps?) that it can under no circumstances discard a specific variable?

Related

Can the gnat compiler find unused specification procedures/functions/variables?

Is there a warning option switch that will identify spec-level procedures, functions, or variables that are not called or referenced anywhere? I've tried the switches below without luck.
This is what I'm currently using:
-gnatwfilmopuvz
-- m turn on warnings for variable assigned but not read
-- u turn on warnings for unused entity
-- v turn on warnings for unassigned variable
When I move unused variables from the spec to the body, the compiler correctly identifies them as not referenced. I would like to understand why the compiler won't identify unused code in the spec, and if there is a way to get it to do so. An excessive number of warnings isn't a concern, because I use the filter field in gnat studio to only look at a few files at a time, and I can easily filter to ignore library packages.
Any help is very appreciated.
The compiler will only detect unused items in the unit it is compiling.
If you have items in a package spec, you can know they are used (or not) only by exploring the whole project's Ada sources. Some tools like AdaControl can do it.
You need a tool for that: gnatelim. Its main use is to reduce the size of the executable, eliminating the object code for unused subprograms, but you can use its output just to get the list of unused subprograms. As far as I know, it will not detect unused variables in the spec, only procedures and functions.
https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gnat_ugn_unw/About-gnatelim.html
Use link-time garbage collection: https://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/gnat_and_program_execution.html#reducing-size-of-executables-with-unused-subprogram-data-elimination
You can then add the linker option --print-gc-sections to instruct the linker to print out a list of all symbols that were garbage collected.

Is there a way to prohibit the declarations of global variables in C/C++ when using GCC?

Say, if a project leader don't want his team members to use global variables, how can he do this technically? Is there an option when building GCC that makes it throw errors when it knows someone has declared a global variable?
And static global is allowed, however.
As requested
How do you plan to use stdin, stdout, stderr and errno (to name but four global variables) if you can't declare global variables? Do you really mean you don't want people to define global variables — though library implementers are exempted because they're required to defined stdout etc?
My suspicion is that you'd do best parsing the output of nm -g file.o (or thereabouts; the options can vary between systems, and the output formats vary dramatically between systems), looking for global variable definitions. You could look for global variable references, but system libraries use them too, so you'd have to know which global variable references are OK and which are not.
I'm not aware of a GCC option for the job, but that doesn't mean it doesn't exist. Have you looked at the manual? I did look and didn't find an appropriate warning — probably because it isn't a common requirement.

Does specifying parameters or variables as __attribute__ ((unused)) allow the compiler to perform any additional optimizations?

I'm particularly curious about LLVM 4.1, but would be interested in other compilers' behavior as well.
According to the GCC documentation (which LLVM supports at least in part), the unused attribute has the following behavior:
This attribute, attached to a variable, means that the variable is meant to be possibly unused. GCC will not produce a warning for this variable.
If the compiler is able to warn you about unused parameters and variables, though, presumably it already knows what parameters and variables are unused without you having to tell it (especially since the unused attribute only indicates that the variable is possibly unused). Therefore, does the unused attribute allow the compiler to perform any additional optimizations, or is its purpose just to allow for more readable code? Also, if the unused attribute does in fact allow the compiler to perform additional optimizations, what happens if you actually end up using a parameter or variable that was specified as unused? LLVM (in XCode) did not seem to complain about this case, though it's possible I wasn't compiling at the right optimization level or with the right warnings enabled.
__attribute__((unused)) doesn't help optimization, and it doesn't mean that the value is necessarily unused. It suppresses warning (if there is a reason for this warning, that is, if the value is indeed unused), that's all.

how can I verify that dead code was stripped from the binary?

My c/obj-c code (an iOS app built with clang) has some functions excluded by #ifdefs. I want to make sure that code that gets called from those functions, but not from others (dead code) gets stripped out (eliminated) at link time.
I tried:
Adding a local literal char[] in a function that should be eliminated; the string is still visible when running strings on the executable.
Adding a function that should be eliminated; the function name is still visible when running strings.
Before you ask, I'm building for release, and all strip settings (including dead-code stripping, obviously) are enabled.
The question is not really xcode/apple/iOS specific; I assume the answer should be pretty much the same on any POSIX development platform.
(EDIT)
In binutils, ld has the --gc-sections option which does what you want for sections on object level. You have several options:
use gcc's flags -ffunction-sections and -fdata-sections to isolate each symbol into its own section, then use --gc-sections;
put all candidates for removal into a separate file and the linker will be able to strip the whole section;
disassemble the resulting binary, remove dead code, assemble again;
use strip with appropriate -N options to discard the offending symbols from the
symbol table - this will leave the code and data there, but it won't show up in the symbol table.

Why gcc gives error of unused variable for local variables but not for global variables?

I have a question regarding gcc. Why I get an error of unused variable when I define the variable locally in a function but not when the variable is global in a unique file?.
I can understand that it can be use for someone else, but to do that then I need to put the external word right?
Thanks in advance.
The compiler has no way of knowing if a global variable is used - it could be used from a compilation unit written in a completely different language, for example.
If by "global in a unique file", you mean "int x;" outside of any function, the it's not the compilers job to detect that, the variable needs to be available to the linker in case another compilation unit needs it (such as errno).
If you meant "static int x" where it's not made available to the linker, this is probably just a choice made by GCC. I don't believe compilers are required to notify of this and it does no real damage other than wasting a few bytes in your address space.
Because global variables can be used on any other place that the compiler cannot known. For instance on a external library o program.
Unused locals can be determined by the compiler. Unused globals can only be determined by the linker, since they can be shared across object files.
In general, the linker doesn't do warnings for code-gen.
When the variable is global, the compiler has not full visibility across all the compilation units in the project - the variable could be modified in another compilation unit. The linker is able to tell that it is unused, probably it will remove it from the object file.
Because if it's global it can be used by another module that gets linked in later.
It's a common idiom to have all your globals defined in a single file. That file may not even have any code, much less code that uses all the variables.
I have encountered the same question when I build the dalvikVM in android2.3 and I got the key of the point. It is because that the parameters of the compiler is too strict:
LOCAL_CFLAGS += -Werror.

Resources