我有这段代码
class IO {
public:
IO(LPC_GPIO_TypeDef* port, int pin) : _pin(pin), _port(port) {};
const int _pin;
LPC_GPIO_TypeDef* const _port;
void test() {
LPC_GPIO0->FIOSET = 0;
}
};
IO led1(LPC_GPIO0, 5);
int main() {
led1.test();
return 0;
}
当我编译它时,我得到了
text data bss dec hex filename
656 0 8 664 298 lpc17xx
我希望const _port和_pin变量存储在flash中,因为它们被标记为const并且初始化值在编译时是已知的,但它们是在.bss部分中分配的。有没有办法让它们驻留在闪存中?
编辑: 我试过这个:
struct IO {
LPC_GPIO_TypeDef* port;
int pin;
void test() const {
//_port->FIOSET = _pin;
LPC_GPIO0->FIOSET = 0;
}
};
const IO led1 = {LPC_GPIO0, 5};
text data bss dec hex filename
520 0 0 520 208 lpc17xx
似乎可以解决问题。为什么它不能用于课程?
答案 0 :(得分:2)
构造函数的参数是变量,您将变量赋给const,这在构造函数中是正常的,但是当智能优化器可能发现静态实例化中常量表达式的出现时,您可能会问很多,因为一般情况要求构造函数接受变量,并且将为一般情况生成代码。
您可以使用模板类实现所需,并将端口/引脚作为模板参数而不是构造函数参数传递。
它可能依赖于编译器,但根据我的经验,你必须将变量声明为静态const以强制它进入Flash,但这不适用于你想要做的事情。
答案 1 :(得分:1)
使用placement new在特定的内存位置创建类的实例:
void * memPtr = 0x???????;
IO* ptrIO = new(memPtr) IO(LPC_GPIO0, 5);
答案 2 :(得分:1)
它不适用于类,因为您实际上是通过函数调用(ctor)初始化const
。这类似于全局范围内的const int foo = rand()
:const
,但不是整数常量表达式。
struct
代码不会调用任何ctor,也不会调用struct
本身或任何成员。
答案 3 :(得分:0)
我想你会看到它确实如此。 data
部分为空,这可能意味着您的常量存储在text
部分中。文本部分是只读的,可能存在于就地执行NOR ROM中,具体取决于ROM映像的构建和运行方式。 (bss部分不计算,因为它不包含任何数据本身,而是告诉加载器0初始化变量需要多少额外内存。)
答案 4 :(得分:0)
第IO led1(LPC_GPIO0, 5);
行做了两件事。它告诉编译器分配长度为8个字节的读/写结构,然后调用intiailization函数即。 construcotr分别在可写静态存储器中将其初始化为LPC_GPIO0和5。此初始化由在调用主函数
您的第二个示例不涉及初始化功能即。一个构造函数,但是分别将非可变内存简单地初始化为“LPC_GPIO0和5”,因此可以直接放在文本部分中。
最终这是一个优化问题,因为构造函数内联且无关紧要,所以可以完全废除它。但是,这可能在一定程度上取决于编译器没有的智能。