我们尝试在二进制对象中嵌入一个 what 字符串,以便我们可以看到已部署的可执行文件或共享库的版本号。通常我们在这个 what 字符串中嵌入标准的 CVS Id 信息。例如,我们可能会嵌入:
const char cvsid[] = "@(#)OUR_TEAM_staging_remap_$Revision: 1.30 $ $Name: $";
在 C 代码中。
来自男人(1)什么:
The what utility searches each filename for occurrences of the pattern @(#) that the SCCS get command (see sccs-get(1)) substitutes for the @(#) ID keyword, and prints what follows up to a ", >, NEWLINE, \, or NULL character.
此变量只有一个实例,而且从未被引用。有人建议这可能会被编译器优化掉。
多年来,我一直在 C 和 C++ 以及各种编译器中使用这种技术,但我还没有看到什么字符串被优化掉了。
有人知道为什么它们没有被优化掉吗?
最佳答案
直到最近(我在 2005 年年中发现了这个问题),才有可能使用:
static const char sccs[] = "@(#)%W% %E%";
或源代码中的类似内容,GCC 和大多数其他编译器不会优化它。从大约那个时候发布的 GCC 开始(可能是 GCC 4.0.x,起源于 2005 年 4 月),那些常量字符串被排除在二进制文件之外。因此,我不得不四处修改我的源代码以使变量在外部可见。编译器不可能单独查看目标文件并得出该字符串未被使用的结论,因为文件外部的某些东西可能会引用它。所以,我的文件现在包含:
#ifndef lint
extern const char jlss_id_filename_c[];
const char jlss_id_filename_c[] = "@(#)$Id$";
#endif /* lint */
好的 - 这是一个混合体;我确实使用 RCS 来存储源代码,但我仍然更喜欢使用 what
来识别文件 - 而且我有自己的 hacked what
做 what
和 ident
加上我自己的一些调整。但是我在一些文件中有声明——不是全部——在所有文件中都有定义。 (在一些警告标志下,现在不记得了,当变量在声明之前定义时,我收到警告。可能是 GCC 中的一个更改解决了这个问题;我不再确定了。)
当我创建一个新文件时,我的模板生成器将“filename_c”替换为正在生成的文件的适当名称。对于 header 也是如此 - 尽管标识字符串仅嵌入一个文件中以避免多次定义。
我更喜欢带有静态常量的旧系统 - 但这已经为我工作了 3 年多。
关于c - SCCS "what"字符串未被编译器优化掉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/484375/