【发布时间】:2018-05-10 21:09:48
【问题描述】:
Edit2 我使用的是 foobar(*bar);在示例中,而不是 *myvar,很尴尬。
编辑这似乎是 MSP430 微控制器的德克萨斯编译器的行为,而不是“c”的东西。澄清一下,下面的代码是使用德州 LTS 编译器 16.9.x 为 MSP430FR5969 16 位(20 位寻址)微控制器使用 code composer studio 7 编译的。结果与 STS 17.9.x 相同。我编辑了代码示例以使其更加明确,这不是命名的事情。除非您明确要求,否则微控制器编译器不会在字边界上对齐结构成员。
我有这样的结构:
struct foo_{
uint8_t low;
uint8_t high;
} foo;
而我正试图变得像这样聪明:
void bar(){
uint16_t * volatile myvar;
myvar = (uint16_t *) &foo.low;
foobar(*myvar);
}
void foobar(uint16_t value){
printf("Value %d\n", value);
}
您希望指针 *myvar 指向 foo.low 地址,但它完全不同。如果我们将可移植性抛到窗外,它在 C 中不应该完全有效吗?
编辑 我已经编辑了代码示例。意外行为是调试器(能够显示来自奇数内存位置的字数据)和实际处理器(将从奇数地址读取字时返回 0xFFFF)中显示的内容不匹配。编译代码有时会失败,有时不是由结构在 FRAM 内存中的实际位置引起的。
【问题讨论】:
-
根据我对结构的理解,这是未定义的行为,因为可以填充结构,也许检查 sizeof(foo) 并查看它是否不是 2
-
你确定它是完全不同的吗?如果您查看十六进制的值(预期值和实际值),您是否看到 any 关系?而且由于放弃了可移植性会导致结果不正确,也许你根本就没有那么聪明。
-
*bar不是指针。请澄清您的问题,最好制作一个 MCVE (minimal reproducible example)。 -
高度依赖于编译器和目标机器。 Struct 并不总是紧密包装(可以填充),大部分时间都对齐到机器字边界以便于访问。
-
这违反了严格的别名,你应该使用
union。除此之外,bar似乎应该 指向&foo.low,但没有minimal reproducible example 就无法判断。
标签: c pointers type-conversion