c++ - 指针转换字节顺序

标签 c++ c compiler-construction embedded endianness

#include "stdio.h"

typedef struct CustomStruct
{
  short Element1[10];
}CustomStruct;

void F2(char* Y)
{
  *Y=0x00;
  Y++; 
  *Y=0x1F;    
}

void F1(CustomStruct* X)
{
  F2((char *)X);
  printf("s = %x\n", (*X).Element1[0]);
}

int main(void)
{
  CustomStruct s;
  F1(&s);

  return 0;
}

上面的 C 代码在我的 PC 上编译和运行时打印出 0x1f00

但是当我将它闪存到嵌入式目标 (uController) 并进行调试时,我发现 (*X).Element1[0] = 0x001f

1- 为什么在 PC 和嵌入式目标上的结果不同?

2- 我可以在此代码中修改什么,以便它在 PC 案例中打印 0x001f, 无需更改代码的核心(通过添加编译器选项或其他可能)。

最佳答案

short 通常是两个字节和 16 位。当你说:

short s;
((char*)&s)[0] = 0x00;
((char*)&s)[1] = 0x1f;

这会将这两个字节中的第一个字节设置为 0x00,将这两个字节中的第二个字节设置为 0x1f。问题是 C++ 没有指定第一个或第二个字节的设置对整体 short 的值有何影响,因此不同的平台可以做不同的事情。特别是,某些平台表示设置第一个字节会影响 short 的 16 位的“最高有效”位,而设置第二个字节会影响 short 的“最低有效”位 的 16 位。其他平台则相反;设置第一个字节影响最低有效位,设置第二个字节影响最高有效位。这两种平台行为分别称为大端和小端。


获得独立于这些差异的一致行为的解决方案是不要以这种方式访问​​ short 的字节。相反,您应该使用语言确实定义的方法(例如按位和算术运算符)简单地操作 short 的值。

short s;
s = (0x1f << 8) | (0x00 << 0); // set the most significant bits to 0x1f and the least significant bits to 0x00.

The problem is that, for many reasons, I can only change the body of the function F2. I can not change its prototype. Is there a way to find the sizeof Y before it have been castled or something?

仅使用 char* 无法确定原始类型和大小。您必须通过其他一些方式知道正确的类型和大小。如果除了 CustomStruct 之外从未调用过 F2,那么您可以像这样简单地将 char* 转换回 CustomStruct:

void F2(char* Y)
{
  CustomStruct *X = (CustomStruct*)Y;
  X->Element[0] = 0x1F00;
}

但是请记住,这样的转换通常并不安全;您应该只将指针转换回它最初转换的位置。

关于c++ - 指针转换字节顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17459252/

相关文章:

c++ - 我如何判断 boost::thread 是否已完成执行?

c++ - 为什么类型推导在(非指针)函数类型上失败

c++ - 当您显式链接一个已经隐式链接的库时会发生什么?

python - 为什么 Python for 循环不像 C for 循环那样工作?

c - 为什么 short 是 2 字节对齐的?

c++ - 是否可以从 llvmContext 回收内存资源?

c - 为什么传入函数时字符串不会以空值终止?

c++ - 如何将模式从Dev-C++中的c++ 98模式更改为支持C++ 0x(基于范围)的模式?

c++ - 引用和数组索引之间有什么区别?

c++ - C++函数参数表中有String类型的情况下,是否可以使用C程序函数调用C++函数?