C 未初始化的变量放入程序内存区。AVR程序设计

C 未初始化的变量放入程序内存区。AVR程序设计,c,gcc,avr,C,Gcc,Avr,在xxx.h文件中,我声明: const struct MenuItem MenuItemA; 在xxx.c文件中,我有一个定义: const struct MenuItem MenuItemA PROGMEM = {textA, MenuItemAFunction, &MenuItemB, 0}; 我还将xxx.h文件包含在我的主.c文件中。 在构建项目时,我收到以下警告: 未初始化变量“MenuItemA”放入程序内存区[-Wuninitialized] 当我在同一个.c文件中有

在xxx.h文件中,我声明:

const struct MenuItem MenuItemA;
在xxx.c文件中,我有一个定义:

const struct MenuItem MenuItemA PROGMEM = {textA, MenuItemAFunction, &MenuItemB, 0};
我还将xxx.h文件包含在我的主.c文件中。 在构建项目时,我收到以下警告:

未初始化变量“MenuItemA”放入程序内存区[-Wuninitialized]


当我在同一个.c文件中有声明和定义时,一切正常,我不知道现在出了什么问题

Joachim是正确的,头文件中的所有定义都需要一个
extern
——否则每次使用头文件(在不同的源文件中)时,都会创建变量的另一个副本。 为了回答您最初的问题,我怀疑变量位于代码部分,因为它是常量,如果删除
const
,它将进入BSS或数据部分,具体取决于它的定义方式。
但是您的主要问题是缺少
extern

,正如您所说,这不是一个错误,只是一个警告,提醒您不要浪费宝贵的闪存用于未初始化的变量

若它确实是未初始化的,那个么似乎并没有必要将它显式地放入progmem中,因为它在progmem中是常量,并且在程序运行期间不能被覆盖(很容易)

您使用它的方式—在包含头文件的所有文件中都有一个,并在一个文件中定义它,这会使其他文件的编译对此抱怨不已。(最好是链接时警告,而不是编译时警告…)

(长篇大论的开头)


我遇到了同样的问题:我想创建一个“插件”框架,我的库的用户可以选择是否添加某个函数指针作为“插件”:在我的库的头文件中,我有一个

extern some_type * const PROGMEM my_array[];

#define enable_my_stuff() some_type * const PROGMEM my_array[2] = {something_of_some_type, NULL}
而我的库的C文件有一个

// Tentative definition which is used when nothing else is there.
some_type * const PROGMEM my_array[2];
这样我有两种情况:要么没有人使用
enable\u my\u stuff()
并且我的数组是空的(这没关系,但是浪费了4个字节),要么使用
enable\u my\u stuff()
,扩展功能被激活,数组内容反映了这一点

它是有效的,但我得到的正是上面的警告。因为它让我恼火,我可能会用另一种方式来实现它



(结束长篇大论)

在头文件中定义变量,这意味着包含头文件的每个文件都将定义该变量。使其
extern
,这样它只在头文件中声明,应该可以更好地工作。好的,现在就可以了,谢谢。我需要预先声明,我认为const struct MenuItem MenuItemA;头文件中有一个声明。为什么不是呢?我没有定义任何值,我在Stephen Prata关于C编程的书中查过,现在我确信const struct MenuItem MenuItemA;头文件中有一个声明,因此我不理解错误。有人能给我解释一下吗?是的,但根据所有基本的C语言书籍const struct MenuItem MenuItemA;是一种声明,因此在不同的源文件中包含xxx.h文件不会产生任何错误。变量(声明后)是否初始化取决于它的去向(代码段、bss或数据段)?否。未初始化的变量进入bss,在数据中初始化。Const变量倾向于进入rodata,但也可以进入代码“否则每次使用头(在不同的源文件中)时,都会创建变量的另一个副本”,如果前面有
static
,则该值为真。这里使用的方式称为“暂定定义”:未初始化的定义被链接器看到,只要它没有被显式定义的定义覆盖就有效。变量位于代码部分,因为它被显式声明要放入
PROGMEM
,而不是因为
const
。。。