我怎样才能让 GCC 在 ROM 中放置一个C++ constexpr

How can I get GCC to place a C++ constexpr in ROM?

本文关键字:constexpr C++ 一个 ROM GCC      更新时间:2023-10-16

我为LPC1114编译,这是一个小的ARM(实际上是Cortex)目标。RAM比ROM更受限制。我使用最新的 Mentor (CodeBenchLite) GCC 编译器 (GCC 4.6.3)。我有一些常量对象,我想在ROM中拥有。据我了解,下面代码中的 ffx 对象应该以 ROM(代码)结束,而是放在 DATA 中。

class flop {
    public:
       int x;
       constexpr flop( int x ) : x(x){}
};
 extern constexpr flop ffx( 1 );

如何说服编译器预先计算对象并将其放置在ROM中?

或者也许我应该问:

  • 我可以以某种方式期望 G++ 编译器为 ffx 生成可 ROMable 数据
  • 如果是这样,我的代码是否正确
  • 如果是这样,这支持哪个 G++ 版本(我使用 4.6,也许我需要 4.7?

====

=======================================

这个 bugzilla 条目 c++/49673 似乎表明我的是一个已知问题,可能在 GCC 4.7 中修复。不幸的是,我更喜欢使用构建的 Mentor/CodeSourcery,它仍然是 4.6.3。所以我想暂时我被这个错误困住了。:(

更新#2:使用gcc 4.7.0测试结果

这确实在 gcc 4.7.0 中得到了修复。代码生成以下汇编程序输出:

    .file   "constexpr.cpp"
    .globl  _ffx
    .section .rdata,"dr"
    .align 4
_ffx:
    .long   1

这可能是你想要的。升级?

我认为您需要一个特定于平台的解决方案。请参阅在内存中查找代码和数据(散射加载):

Scatterload 允许您将应用程序分区为分布在整个地址映射中的多个单独的代码和数据区域。这些区域的位置在加载时间和运行时之间可能有所不同:

    加载
  1. 区域包含应用程序在上电/加载时(通常为 ROM)使用的应用程序代码和/或数据。

不要仅仅依赖 gcc,而是尝试按照上面提供的链接中的建议使用armlink

更新:我看到了您注意到的 gcc 错误。LLVM/MinGW同样毫无希望。但是,我一直在使用GCC 4.6,我认为这里有一些可能对您有所帮助:

struct Data
{
    int i;    
};
constexpr Data getData() { return Data{1}; }

如果您没有 ctor,而是具有 constexpr 函数,并尝试生成汇编器输出,则输出通常为空(没有.data部分)。如果你使用它来初始化一些变量(在全局范围内),如下所示:

const Data foo = getData();

你会得到一个程序集,如下所示:

    .file   "constexpr.cpp"
    .section .rdata,"dr"
    .align 4
__ZL3foo:
    .long   1

(这是使用g++ -std=c++0x -S命令行)。这对你有用吗?

根据

我的经验,const数据被放入只读部分,因此本节中的所有数据都可以进入ROM(或编程到FLASH中)。

GCC 链接器指令文件 (*.ld) 可以将地址分配给不同的部分。

另一种选择是将大型数据结构(如字体)放入汇编语言中。 汇编语言可以比 C 或C++语言更容易将数据放入段中。

我们的下一个目标是将数据与可执行文件分开。 这缩短了可执行文件并减少了可执行文件的测试时间。