【问题标题】:Best Practice - Consolidating duplicate text literals across many translation units最佳实践 - 跨多个翻译单元合并重复的文本文字
【发布时间】:2016-06-22 16:14:59
【问题描述】:

我们公司的静态分析工具显示有重复的字符串(文本字面量)。问题是它们分布在许多翻译单元(源文件)中。

例如字符串“NULL console pointer”在module_a.c中存在1次,在module_b.c中存在5次,在module_f.c中存在1次。

我们还制定了编码指南,规定不得有全局变量。

我们希望头文件中没有变量。

我们的平台是一个嵌入式系统,因此合并常量文本将为其他目的提供空间(并使程序加载更快)。换句话说,文本文字应该只有一个实例。

那么,什么是跨多个翻译单元整合常量文本字面量的有效设计或架构?

是否存在不值得合并重复的长度限制(例如字符串"\r\n"

我们更喜欢性能高效的解决方案,例如更喜欢直接访问而不是调用 getter 函数。

(注:此时文本不需要翻译成多种语言。)

语言:C 和 C++(代码库更多是 C 语言而不是 C++)。
处理器:ARM Cortex A8
平台:嵌入式系统,安全、质量和性能至关重要(医疗设备)。
编译器:IAR Embedded Workbench(用于 ARM 处理器)。

编辑 1:链接器未合并
我扫描了 BIN 文件,它确实包含多个“NULL 控制台指针”实例。

链接器有“合并重复部分”选项,我检查了它。二进制文件仍然包含重复项。

【问题讨论】:

  • 无论如何,大多数现代链接器都能正确优化,我会简单地忽略这种情况下的 SCA 工具警告。
  • 这个问题的答案解释了编译器可以自动执行这样的重复数据删除:stackoverflow.com/questions/11399682/…
  • @ThomasMatthews 我并不是说你的问题是重复的。只是想提供一些信息。
  • 编译器将进行常量折叠并消除大部分(可能是所有)重复项 - 如果您使用 LTO,也可以跨编译单元。
  • 如何将所有字符串放在一个全局外部数组中,并使用枚举类型为索引赋予有意义的名称? (虽然它不是完全“没有全局变量”)

标签: c++ c build embedded code-duplication


【解决方案1】:

如果只关心字符串文字,则不需要更改代码。

您需要做的是研究如何在您的编译器上启用字符串池。这是一个优化器选项,用于在整个程序中寻找相同的字符串文字。如果它发现相同的文字被使用了两次,它将把它们都分配到相同的内存地址。这应该在多个翻译单元中工作。

(在 GCC 中这称为 -fmerge-constants。我不知道在 IAR 中它叫什么。)

【讨论】:

    【解决方案2】:

    我认为如果链接器确实存在重复数据删除问题,我会使用静态函数来传递文字字符串:

    // header file
    
    struct text
    {
      static const char* hello_world();
    };
    
    
    // one source file
    // #include "text.hpp"
    const char* text::hello_world() {
      static const char _[] = "Hello, World";
      return _;
    }
    
    
    
    // use case
    
    // #include "text.hpp"
    #include <iostream>
    
    int main()
    {
      std::cout << text::hello_world() << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-01-02
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 2015-03-29
      • 2013-04-22
      • 1970-01-01
      相关资源
      最近更新 更多