为啥 AVR-GCC 编译器在使用相同的变量但作为 PROGMEM 重载时会引发错误?
Posted
技术标签:
【中文标题】为啥 AVR-GCC 编译器在使用相同的变量但作为 PROGMEM 重载时会引发错误?【英文标题】:Why AVR-GCC compiler throws an error when overloading with the same variables but as PROGMEM?为什么 AVR-GCC 编译器在使用相同的变量但作为 PROGMEM 重载时会引发错误? 【发布时间】:2021-07-31 17:22:48 【问题描述】:我的问题更像是:为什么编译器“认为” “PROGMEM 变量” 与 “普通变量” 相同>?是因为PROGMEM-keyword is "just" a macro 仅此而已吗?还是出于其他原因? 是否有任何解决方法..?
问题演示:
让我们考虑下面的例子:
class object
public:
object(int* variable);
object(int* variable PROGMEM);
;
它抛出 error: 'object::object(int*)' cannot be overloaded
就好像它是一样的。
sketch_jul31a:4:3: error: 'object::object(int*)' cannot be overloaded
object(int* variable PROGMEM)
^~~~~~
sketch_jul31a:3:3: error: with 'object::object(int*)'
object(int* variable)
^~~~~~
exit status 1
'object::object(int*)' cannot be overloaded
结尾:
我前段时间在开发图书馆时遇到了这个问题,我在 arduino-forum 上问过这个问题,但我没有任何答案,所以我想了很长时间后才问过一次再次,在这里。
【问题讨论】:
该注释对于作为普通值的函数参数没有意义。重载指向程序的指针与指向数据内存的指针是有道理的,但这必须是指针类型的一部分——不记得是否有注释。 PROGMEM 是链接器存储变量的信息。它与变量类型无关。 @Mat 这是我的错,我在发布之前忘记了 * 哈哈 @Juraj 太可悲了.. 这正是我所期待的答案... 我希望有一个解决方法...... 【参考方案1】:您不能期望编译器将链接器部分视为类型限定符,但您可以为 const int*
定义重载,这非常接近 PROGMEM(ROM 位置)的语义。
我想知道你打算用const int*
做什么。你所能做的就是读取它,所以它基本上相当于一个普通的常量int
值,增加了两个字节的 ROM 成本。
【讨论】:
太棒了! 像const int* variable PROGMEM
这样的东西是有意义的,因为PROGMEM 无论如何都是不变的。这只是我的一个“愚蠢”示例,在我的情况下 i had to store a banch of weights and biases (如果 PROGMEM 用于只读目的),但最后我逃脱了 MACROS..
我明白了。很高兴能帮到你:)【参考方案2】:
__attribute__((progmem))
是编译器功能,而不是 C++ 语言功能,因此它不参与重载决议。 object(int variable);
和 object(int variable PROGMEM);
在 C++ 中看起来像是 object(int variable);
的双重声明。
【讨论】:
以上是关于为啥 AVR-GCC 编译器在使用相同的变量但作为 PROGMEM 重载时会引发错误?的主要内容,如果未能解决你的问题,请参考以下文章
avr-gcc:如何将 __attribute__((address)) 与 EEMEM 一起使用?