使用 while(1) 在 main() 中将结构实例声明为 static/local

Declaring struct instances as static/local in main() with while(1)

我正在 e2 工作室使用 KPIT GNUARM 16 工具链开发微控制器 RZA1。我不是这方面的专家,所以我会尽力解释这个问题。该问题与我的代码中定义的结构 mainwindow 有关,它包含图形界面的重要功能:

typedef struct
{
    page_t      pages[MAXNUMPAGE];
    logger_t    storico;
    messagges_t messaggio;
    graph_t     grafico;
} mainwindow_t;

main() 函数中,我声明了这个结构的 local 实例,因为它包含一个 while(1) 循环,用于在用户交互时刷新 GUI 应用程序(即点击按钮)。我遇到的问题是,如果声明 mainwindow_t 的实例时使用或不使用 static 关键字,程序的执行方式就会有所不同。例如,

main()
{
    static mainwindow_t mainwindow;
    ....
    init_pages(mainwindow.pages);
    while(1)
    {
        page_update(mainwindow.pages);
    }
}

工作得很好,而只有 mainwindow_t mainwindow; 似乎在函数 init_pages() 中所做的更改没有效果:数组 page[MAXNUMPAGE] 的全部内容未初始化。

因此,我的问题是:如果该函数基本上从不 returns ,函数内部数组的非静态局部声明和静态局部声明之间是否应该存在任何功能差异?

这个问题与变量是否在栈上无关。它与初始化有关。

具有静态存储持续时间的变量,即具有static关键字的文件范围变量或局部变量,被隐式初始化以便(松散地说)所有具有算术类型初始化为0,所有指针变量初始化为NULL.

相比之下,具有自动存储持续时间的变量,即在函数内部声明的变量,如果没有显式指定,不会初始化初始化器,其值为 indeterminate.

虽然您没有显示您的初始化函数,但它显然没有设置 mainwindow.pages 中的所有字段,并且取决于其他字段是否被零初始化。当 mainwindow 被声明为非静态时,这会导致您的程序读取一些导致 undefined behavior 的不确定字段,这解释了为什么当您尝试 trim 代码时问题神秘地消失了。

mainwindow 添加初始化程序可解决此问题,方法是设置任何显式列出的字段,同时将静态对象初始化规则应用于任何未显式初始化的剩余字段。