我正在使用嵌入式 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 问题。 调试器也会验证内存中的值是否为 631237200。
在某些嵌入式系统中,静态初始化并未设置为自动发生。这违背了 C 规范,但有时就是这样。请注意,这对于 data 和 bss 段可能都是如此,即您可能会发现未初始化的静态变量也可能不会初始化为零。
不幸的是,这个问题的解决方案是特定于系统的。您可能会在编译器系统文档中找到一些内容,可以让您调用静态元素的初始化。
" Cycle Start: %d", cycle.startTime
很容易打印出> 64k 的值。 我怀疑是填充问题。 但是关于 printf() 的较低建议适用,即使它们没有解释这个问题。
cycle
cycle.startTime = 315618000
。 你的 int/unsigned 大小可能是 2,因此初始化溢出。 相反:
Cycle cycle = {
315618000LU,
1200,
0
};
您的 printf()
还应该使用 uint32_t 的匹配格式说明符
#include <inttypes.h>
printf("Cycle Start: %" PRIu32 "\n", cycle.startTime);
printf("Length : %" PRIu16 "\n", cycle.length);
您可能可以通过查看汇编代码来了解发生了什么。不知道你的编译器是不是GCC。如果是 -S 标志应该生成一个名为输入文件但带有 .s 扩展名的汇编文件。另一个可能出错的地方是 printf 函数。如果您没有使用像
int printf(const char *fmt, ...)
在我所知道的至少一种架构上,所有可变参数条目都具有最大对齐,因为该函数不知道它正在获取什么。普通函数通过声明的类型对齐方式在堆栈上传递值。如果 printf 没有原型,C 语言将假定所有参数都是 int 并尝试以这种方式传递它们。同时 printf 函数本身将尝试将参数作为可变参数拉取,并且它很容易在这里或那里滑动几个字节。