为什么编译器将此变量初始化为错误的值? 这是对齐问题吗?

我正在使用嵌入式C编译器(ARM cortex-m3芯片),它似乎将错误的值初始化为结构。 为什么会这样? 如果是对齐问题,编译器是否应该知道将int32u与4字节边界对齐?

注意:printf只会抛出串行端口的字节。 这个芯片上没有stdio.h实现。

typedef struct { int32u startTime; int16u length; int32u offTime; } Cycle; Cycle cycle = { 315618000, 1200, 0 }; void init() { printf("\r\nInitialized! Cycle Start: %d", cycle.startTime); cycle.startTime = 315618000; cycle.length = 1200; printf(" Cycle Start: %d", cycle.startTime); } 

输出:初始化! 循环开始:631237200循环开始:315618000

注意::这不是printf问题。 调试器也会将内存中的值validation为631237200。

在某些嵌入式系统中,静态初始化不会自动设置。 这违反了C规范,但有时候就是这样。 请注意,对于数据段和bss段,这可能都是正确的,即您可能会发现未初始化的静态也可能不会初始化为零。

不幸的是,解决方案是系统特定的。 您可以在编译器系统文档中找到允许您调用静态元素初始化的内容。

[编辑]我建议下面的sizeof(int)== 2可能不是 " Cycle Start: %d", cycle.startTime很容易打印出> 64k的值。 我怀疑填充问题。 但是关于printf()的较低建议适用,即使它们没有解释这个问题。


有效cycle的初始化执行cycle.startTime = 315618000 。 你的int / unsigned大小可能是2,因此初始化溢出。 代替:

 Cycle cycle = { 315618000LU, 1200, 0 }; 

你的printf()也应该使用uint32_t的匹配格式说明符

 #include  printf("Cycle Start: %" PRIu32 "\n", cycle.startTime); printf("Length : %" PRIu16 "\n", cycle.length); 

您可以通过查看汇编代码来了解发生的情况。 我不知道你的编译器是否是GCC。 如果是-S标志,则应生成一个名为输入文件但扩展名为.s的程序集文件。

有了它,您应该能够查看分配给全局结构变量的值。

另一个可能错误的是printf函数。 如果您没有使用函数原型将其声明为类似int printf(const char *fmt, ...)的varargs函数int printf(const char *fmt, ...)则调用将完成错误。

在我所知道的至少一个架构中,所有vararg条目都具有最大对齐,因为该函数不知道它得到了什么。 普通函数使用声明的类型对齐在堆栈上传递值。 如果printf没有原型,C语言将假定所有参数都是int并尝试以这种方式传递它们。 与此同时,printf函数本身将尝试将参数拉为varargs,并且它可以轻松地在此处和那里滑动几个字节。