סטנ*_*ונן 4 c variables optimization gcc arm
我正在使用ARM-GCC v4.9(2015-06-23发布)用于STM32F105RC处理器.
我搜索了stackoverflow.com,我发现这是为了试图说服gcc 不要优化全局变量,如下所示:
static const char AppVersion[] __attribute__((used)) = "v3.05/10.oct.2015";
Run Code Online (Sandbox Code Playgroud)
然而,令我惊讶的是,编译器优化了AppVersion变量!
顺便说一句:我正在使用优化级别-O0(默认).
我也尝试使用volatile关键字(如其他线程所示),但它也不起作用:(
我已经尝试(void)AppVersion;但它不起作用...
智能编译器!?太聪明我想...
在此期间,我printf(AppVersion);在我的代码中使用了一些地方,只是为了能够保留版本......但这是一个粗野的解决方案:(
所以,问题是:是否有任何其他技巧可以完成这项工作,即保持该版本是否被GCC优化?
[编辑]:
我也尝试过这样(即没有static):
const char AppVersion[] __attribute__((used)) = "v3.05/10.oct.2015";
Run Code Online (Sandbox Code Playgroud)
......它也不起作用:(
鉴于存在"静态",所有声明都要求编译器在文件中的某个任意位置以某种顺序包含表示字符串"v3.05/10.oct.2015"字符的字节,但不要打扰告诉任何人把它们放在哪里.鉴于编译器可以合法地在代码图像文件中的某处写入该字节序列,无论它是否出现在代码中的任何地方,这样的声明实际上并不是非常有用.可以肯定的是,这样的序列不可能完全偶然出现在代码中,因此扫描二进制图像可能是一种可靠的方法来确定它出现在代码中,但总的来说它更好一些有一些肯定地确定可以找到字符串的方法.
如果字符串未声明为static,则需要编译器告诉链接器它在哪里.由于链接器通常输出各种位置的所有符号的名称和地址,包括符号表,调试信息文件等,它们可以以链接器一无所知的各种方式使用,它可能能够分辨代码中没有使用符号,但通常不知道某个其他实用程序是否可能期望在符号表中找到它并使用它.一个说明符号被"使用"的指令将告诉链接器即使它不知道任何对该符号感兴趣的东西,但是在更大的宇宙中,链接器一无所知对它感兴趣.
每个编译单元通常会向链接器提供一些信息并说"这是一些东西;我需要一个符号来开始它,但我可以从中计算所有内部的所有地址".链接器无法知道这些blob的哪些部分实际被使用,所以它别无选择,只能逐字接受整个事物.如果编译器在其blob中包含未使用的静态声明,则它们会将其传递给输出文件.另一方面,编译器知道如果它没有为该blob中的某些东西导出符号,那么下游的任何其他人都无法找到它,无论该对象是否被包含在内; 因此,能够包括这样的blob通常没什么好处,并且编译器编写者通常必须推理提供强制这种包含的特征.
不幸的是,我不知道这样做的编译指示。
然而,还有另一种解决方案。将 AppVersion 更改为:
static char * AppVersion = "v3.05/10.oct.2015";
Run Code Online (Sandbox Code Playgroud)
并添加:
__asm__ ("" : : "" (AppVersion));
Run Code Online (Sandbox Code Playgroud)
到您的主要功能。
你看我删除了 'used' 属性,根据文档,这是一个函数属性。
其他解决方案:gcc 是否有任何选项可以在 ELF 二进制文件中添加版本信息?
虽然我发现这个是最简单的。这基本上不会让编译器和链接器删除 AppVersion,因为我们告诉它这个内联程序集使用它,即使我们实际上没有插入任何内联程序集。
希望这会让你满意。
作者:Andre Simoes Dias Vieira
原文链接:https : //answers.launchpad.net/gcc-arm-embedded/+question/280104