如何让GCC在ROM中放置C++ constexpr?

Wou*_*jen 6 c++ gcc arm constexpr

我为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 );
Run Code Online (Sandbox Code Playgroud)

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

或者我应该问:

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

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

这个bugzilla条目c ++/49673似乎表明我的已知问题,可能已在GCC 4.7中修复.不幸的是,我更喜欢使用内置的Mentor/CodeSourcery,它仍然是4.6.3.所以我想暂时我会遇到这个bug.:(

dir*_*tly 1

更新#2:gcc 4.7.0 的测试结果

这确实在 gcc 4.7.0 中得到了修复。您的代码产生以下汇编器输出:

    .file   "constexpr.cpp"
    .globl  _ffx
    .section .rdata,"dr"
    .align 4
_ffx:
    .long   1
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

更新:我看到了你注意到的 gcc bug。LLVM/MinGW 同样无望。不过,我一直在使用 GCC 4.6,我认为以下内容可能对您有所帮助:

struct Data
{
    int i;    
};
constexpr Data getData() { return Data{1}; }
Run Code Online (Sandbox Code Playgroud)

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

const Data foo = getData();
Run Code Online (Sandbox Code Playgroud)

你会得到如下的程序集:

    .file   "constexpr.cpp"
    .section .rdata,"dr"
    .align 4
__ZL3foo:
    .long   1
Run Code Online (Sandbox Code Playgroud)

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