我怎样才能让 GCC 在 ROM 中放置一个C++ constexpr
How can I get GCC to place a C++ constexpr in ROM?
我为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 允许您将应用程序分区为分布在整个地址映射中的多个单独的代码和数据区域。这些区域的位置在加载时间和运行时之间可能有所不同:
加载
- 区域包含应用程序在上电/加载时(通常为 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++语言更容易将数据放入段中。
我们的下一个目标是将数据与可执行文件分开。 这缩短了可执行文件并减少了可执行文件的测试时间。
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- constexpr上下文中std::initializer_list的验证
- constexpr构造函数需要常量成员函数时出现问题
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- C++constexpr实现差异
- 添加静态constexpr成员是否会更改结构/类的内存映射
- C++中的Constexpr迭代程序