【问题标题】:C++ global constant in RAM not ROMRAM 中的 C++ 全局常量而不是 ROM
【发布时间】:2017-01-12 13:29:02
【问题描述】:

早安,

我注意到当我有以下代码时:

int foo(const int arg){
    return arg*10;
}

const int MY_VAR = foo(10);

main(){

    while(true){

    }
}

然后将 MY_VAR 放在 RW 数据段 (RAM) 中。老实说,我预计会出现编译器错误。我正在使用 GNU ARM 6.2 2016q4 版本。

如果我创建 MY_VAR constexpr,则会收到编译器错误。如果我制作 foo constexpr 然后,正如预期的那样,MY_VAR 被放入 .text 部分(即在 ROM 中)。

由于 constexpr 变量不能用作 extern,我将不得不将 const 变量用于真正的全局常量。

有哪些方法可以自动(即编译器警告或错误)检测未将常量分配给 ROM?

我确实想使用函数来初始化一些 const 全局变量。虽然我想捕捉函数不是自动 constexpr 的情况。

【问题讨论】:

  • 常量MY_VAR 是一个全局变量。它在 RAM 中分配
  • ROM 与 RAM 的只读部分不同。
  • 如果你把它编译成标准C,你确实会得到一个编译器错误。经验丰富的老手在程序发布之前总是需要一些时间来阅读地图文件,看看是否有什么可疑的东西最终进入了 RAM。
  • OP 指定他想在其他源文件中声明变量extern,所以不,它不适用于constexpr
  • @gmug:这是错误的。该语言不需要这样做,编译器(或链接器)会尽可能将它们放在 ROM 中。由于函数调用,这是不可能的。

标签: c++ gcc arm embedded


【解决方案1】:

您的常量变量MY_VAR 使用函数调用的结果进行初始化 - 这意味着它无法在编译时初始化,因此无法放入 ROM。初始化是在您的应用程序在运行时启动期间完成的。

如果完成此类放置,则无法生成警告 - 毕竟,您告诉编译器这样做。

但是,您可以让链接器生成链接映射并手动检查您的所有常量是否实际上都在正确的段中结束。

【讨论】:

  • 只是指出,如果用 constexpr 函数初始化,这不是问题。
  • @Flip 这是正确的 - 但是,constexpr 函数不能具有全局范围的结果。
猜你喜欢
  • 2020-07-09
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 2019-07-24
相关资源
最近更新 更多