Related discussion: http://gcc.gnu.org/ml/gcc/2005-03/msg00181.html Given the following, static char const rcsid[] = "$Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $"; int main() {} When compiled with GCC 3.4.3, at -O2, the ident string above will _not_ appear in the executable. This is apparently expected behavior. However, gcc -fkeep-static-consts -O2 t.c did not retain the ident string, rcsid, defined above. Shouldn't -fkepp-static-consts have ensured that this static constant would appear in the executable? The logic in wrapup_global_declarations (toplev.c) doesn't look quite right: else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) && (optimize || !flag_keep_static_consts || DECL_ARTIFICIAL (decl))) needed = 0; If 'optimize' is asserted above then flag_keep_static_consts will not be tested. Perhaps it should read as follows? && ((optimize && !flag_keep_static_consts) Alternatively, I wonder if flag_keep_static_consts should be tested earlier at a higher level, for example: if (flag_keep_static_consts) /* needed */; but I'm not sure about which of the earlier tests which assert needed = 0; are mandatory and which are optional.
Nope, -fkeep-static-consts only control when optimization is not on: From the docs: Emit variables declared @code{static const} when optimization ____isn't____ turned on, even if the variables aren't referenced. Enphise mine. Use the "used" attribute if you want to keep unused constants.
"Emit variables declared @code{static const} when optimization isn't turned on, even if the variables aren't referenced." How odd. I should've checked the docs, but this brief explanation in the help line made a lot of sense to me. -fkeep-static-consts Emit static const variables even if they are not used Also, since the constant *was kept* when I compiled _without_ optimization, the idea of passing a switch telling the compiler to do something that it seemed to already be doing by default didn't make sense to me. The comments inside toplev.c say the following: /* Nonzero means that we should emit static const variables regardless of whether or not optimization is turned on. */ int flag_keep_static_consts = 1; which makes sense to me. Note that this is the default setting. So ... coming back to the if statement in toplev.c: else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) && (optimize || !flag_keep_static_consts || DECL_ARTIFICIAL (decl))) needed = 0; At present, If optimize is set, the unused static constant will always be eliminated and -fkeep-static-consts will have no effect, and there is no way to override this behavior (except for __attribute__ ((used))). This agrees with the documentation, but disagrees with the comment in the code, and with the spirit of the help message. It also doesn't make sense to me that -fkeep-static-consts would be ignored. In fact, it seems to me that -fkeep-static-consts should override the optimization setting. Otherwise, only -fno-keep-static-consts has any effect and that is only when optimization is not enabled. I think the behavior of -fkeep-static-consts should be modified so that setting this switch overrides the optimization level. Thus, the documentation would need to be changed as well. Otherwise, the internal comments and the help line are wrong. Regarding the "used" attibute, I thought that I'd tried that, and it didn't work. But upon retesting, it does seem to have the desired effect of keeping the static const around (maybe I specified the "unused" attribute by mistake in my test). Note that the "used" attribute is described only under "function attributes" and not under "variable attributes" in the documentation: used This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly. (see: http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Function- Attributes.html#Function-Attributes) It would be helpful if the documentation were updated to describe the behavior of the `used' attribute when apllied to variables.
Don't belive the comments in the source. Also the --help is way out of date. you want to use the used attribute like so: static char const rcsid[]__attribute__((used)) = "$Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $"; And this works for me.
Subject: Re: -fkeep-static-consts with -O asserted doesn't keep consts On Fri, 4 Mar 2005, pinskia at gcc dot gnu dot org wrote: > Don't belive the comments in the source. Also the --help is way out of > date. Both comments being wrong and --help being wrong are bugs. This PR should be kept open until whatever semantics are agreed are documented in the manual, in --help output, in comments and are implemented.
Here is some detail on my proposed change in behavior: 1) Change the default setting to -fno-keep-static-consts: /* Nonzero means that we should emit static const variables regardless of whether or not optimization is turned on. */ int flag_keep_static_consts = 0; 2) have flag_keep_static_consts affect only the behavior of the compiler when 'optimize' is asserted: Change the logic in wrapup_global_declarations (toplev.c) to read: else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) && (optimize && !flag_keep_static_consts) || DECL_ARTIFICIAL (decl))) needed = 0; This change would imply that: 1) -fkeep-static-consts and -fno-keep-static-consts will have no effect at -O0. Presently, -fno-keep-static-consts would eliminate the unreferenced static const variable if it isn't referenced. This would no longer be the case. At -O0, the compiler would always leave unrefereced static consts alone. 2) If optimization is asserted (ie, -O1 and above), then always eliminate static const's that aren't referenced, unless -fkeep-static-consts is asserted.
from http://gcc.gnu.org/ml/gcc/2005-03/msg00491.html I think that the switch name -fkeep-static-consts might be more consistenly named if it was given the opposite sense and named something like -fdelete-unused-static-consts. The idea here is that by asserting the switch a particular optimization is _enabled_. Thus the optimizations performed at each level can be consistently enumerated by asserting a particular set of switches which enable specific optimizations. This would change the present user interface, however, I doubt that anyone is making extensive use of the current interface because at present only -fno-keep-static-consts, asserted at -O0 (no optimization), actually changes the default behavior of the compiler.
I guess that tagging the bug with a "documentation" keyword doesn't necessarily say that the bug is being classified only as a defect in the documentation. However, if that is the meaning of this keyword, then I'd like to clarify the bug report. - yes, the documentation, source code commments and -help are either incomplete or do not accurately describe present behavior. - -fkepp-static-consts behaves in an unexpected manner, in that when asserted, it enables a behavior that is already enabled by default. And interestingly, it has no effect when optimization is enabled. - Only -fno-keep-static-consts has an effect, and then only when optimization is not enabled. - In general, I think it would be best if switches which selectively control optimizations, enable that optimization when asserted, and disable the optimization when negatively asserted (ie, when prefixed with no- ...). Thus I recommend that -fkeep-static-consts be deprecated, and replaced by a new switch, named something like -fdelete-unused-static-consts. It would also be a good idea to look at the other optimization enabling switches to ensure that they follow this convention. Ideally, each optimization level such as O1, O2, O3, Os, and Ot would be definitively and completely expressed by the selective optimization options they enable.
(In reply to comment #7) > - yes, the documentation, source code commments and -help are either > incomplete or do not accurately describe present behavior. Confirmed. Patches are welcome. > - -fkepp-static-consts behaves in an unexpected manner, in that when asserted, > it enables a behavior that is already enabled by default. And interestingly, > it has no effect when optimization is enabled. I would argue that it will make sense that -fkeep-static-consts keeps static consts variables independently of whatever other flags. Then, we could say that it is enabled by default at -O0 and needs to be specifically enabled at higher levels. > - Only -fno-keep-static-consts has an effect, and then only when optimization > is not enabled. -fno-keep-static-consts should have the effect of disabling -fkeep-static-consts, either because it was enabled by default (at -O0) or because it appeared earlier in the command-line. > - In general, I think it would be best if switches which selectively control > optimizations, enable that optimization when asserted, and disable the > optimization when negatively asserted (ie, when prefixed with no- ...). Thus > I recommend that -fkeep-static-consts be deprecated, and replaced by a new > switch, named something like -fdelete-unused-static-consts. It would also be That sounds good, but deprecating bad names in released versions is bad. The option is there and there are not many bug reports like these, so it doesn't seem to be so problematic. Let's fix the above problems first. > a good idea to look at the other optimization enabling switches to ensure that > they follow this convention. Ideally, each optimization level such as O1, O2, > O3, Os, and Ot would be definitively and completely expressed by the selective > optimization options they enable. Ot? What is that level supposed to do? Ideally, that sounds good. In practice, there are too many and too diverse optimizations to warrant particular flags.
FWIW- I ran into this "bug" too, in the same usecase as Gary. I think the current behavior is close to useless and should be changed as outlined above. Cheers Hans
Hi, I recently was bitten by the same "feature" and I would like to add a few points (important, IMHO) to the discussion. 1. I noticed that combining -g with -O2 kept unused static constants in the object files up to version 4.4, but not in 4.5 or 4.6. My tests were all done on Red Hat Linux systems (RHEL or Fedora) rather than on vanilla gcc - I doubt it matters but I think it needs to be mentioned. 2. I must state that from my prospective the current behaviour is a problem. There is an optimization that cannot be turned off selectively, even as many other optimizations can. The behavior of -fkeep-static-consts is illogical, as others have mentioned. 3. The use case of version control keywords is a very important one. This thread http://gcc.gnu.org/ml/gcc/2005-04/msg01429.html shows that it is not regarded as such by the GCC team. I do not intend to start a discussion here, but with all due respect there are lots of very practical considerations that may be irrelevant for GCC itself but very relevant in other contexts. I will only make a general statement as follows: 4. GCC optimizes unused static consts away as it understands that they cannot be accessed by any program of which the const is a part. It misses the possibility that the resulting object may be input to another program (e.g., ident(1) or strings(1)) and thus there may be a legitimate reason to keep the const even as other optimizations are applied. 5. I can only regard __attribute__((unused)) as a very poor workaround because it makes the code non-portable and requires, apart from the definition of the constant, at least some preprocessor trickery like #ifdef __GNUC__ / #else / #endif. Dealing with the issue with a compiler option is much better. This begs for being patched, probably along the lines of what Gary Funck suggested. I may be willing to look at the code and submit such a patch, but I would first appreciate a bit of procedural guidance from developers. This bug, albeit still NEW and unassigned, is against a very old version. Should a new bug be opened and tracked? Given that a patch would change the default behaviour of an option, and the documented "we don't really understand the need for this" opinion (highly respected but contested), is there a reasonable chance that a patch would be accepted? Has a patch like this been submitted and rejected in the past? Verifying it "from outside" seems a non-trivial task by itself. Manuel (comment #8)? Anyone? I'd appreciate a reaction before diving in. Thanks, Oleg.
I was just bitten by this bug myself when upgrading to gcc-4.6. The symptom was exactly the same as Oleg describes: -g -O2 kept the constants under gcc-4.1 -g -O2 removes the constants under gcc-4.6 This has been a problem for the users of the library I maintain, and I agree with previous posters (Gary, Oleg, etc...) that a fix would be very welcome. Could we have a comment from the gcc team as to whether a patch would be welcome? Best regards