简体   繁体   English

我可以像这样投射指针吗?

[英]Can I cast pointers like this?

Code: 码:

unsigned char array_add[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

...

if ((*((uint32_t*)array_add)!=0)||(*((uint32_t*)array_add+1)!=0))
{
 ...
}

I want to check if the array is all zero. 我想检查数组是否全为零。 So naturally I thought of casting the address of an array, which also happens to be the address of the first member, to an unsigned int 32 type, so I'll only need to do this twice, since it's a 64 bit, 8 byte array. 所以我自然而然地想要将一个数组的地址(也恰好是第一个成员的地址)转换为unsigned int 32类型,因此我只需要执行两次,因为它是64位,8字节阵列。 Problem is, it was successfully compiled but the program crashes every time around here. 问题是,它已成功编译,但程序每次都在这里崩溃。

I'm running my program on an 8bit microcontroller, cortex-M0. 我在8位微控制器cortex-M0上运行我的程序。

How wrong am I? 我有多难?

In theory this could work but in practice there is a thing you aren't considering: aligned memory accesses. 理论上这可行,但在实践中有一件事你没有考虑:对齐的内存访问。

If a uint32_t requires aligned memory access (eg to 4 bytes), then casting an array of unsigned char which has 1 byte alignment requirement to an uint32_t* produces a pointer to an unaligned array of uint32_t . 如果uint32_t需要对齐的内存访问(例如,4个字节),则将一个对uint32_t*具有1字节对齐要求的unsigned char数组生成一个指向未对齐的uint32_t数组的指针。

According to documentation : 根据文件

There is no support for unaligned accesses on the Cortex-M0 processor. 不支持Cortex-M0处理器上的未对齐访问。 Any attempt to perform an unaligned memory access operation results in a HardFault exception. 任何尝试执行未对齐的内存访问操作都会导致HardFault异常。

In practice this is just dangerous and fragile code which invokes undefined behavior in certain circumstances, as pointed out by Olaf and better explained here . 在实践中,这只是危险且脆弱的代码,在某些情况下会调用未定义的行为,正如Olaf所指出的那样,并在此更好地解释。

To test multiple bytes as once code could use memcmp() . 要测试多个字节作为一次代码可以使用memcmp()

How speedy this is depends more on the compiler as a optimizing compiler may simple emit code that does a quick 8 byte at once (or 2 4-byte) compare. 这有多快取决于编译器,因为优化编译器可以简单地发出快速8字节(或2 4字节)比较的代码。 Even the memcmp() might not be too slow on an 8-bit processor. 甚至memcmp()在8位处理器上也可能不会太慢​​。 Profiling code helps. 分析代码有帮助。

Take care in micro-optimizations, as they too often are not efficient use of coders` time for significant optimizations. 注意微观优化,因为它们往往无法有效地使用编码器时间进行重大优化。

unsigned char array_add[8] = ...
const unsigned char array_zero[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
if (memcmp(array_zero, array_add, 8) == 0) ... 

Another method uses a union . 另一种方法使用union Be careful not to assume if add.arr8[0] is the most or least significant byte. 小心不要假设add.arr8[0]是最重要或最不重要的字节。

union {
  uint8_t array8[8];
  uint64_t array64;
} add; 

// below code will check all 8 of the add.array8[] is they are zero.
if (add.array64 == 0)

In general, focus on writing clear code and reserve such small optimizations to very select cases. 一般而言,专注于编写清晰的代码并为非常精选的案例保留这种小优化。

I am not sure but if your array has 8 bytes then just assign base address to a long long variable and compare it to 0. That should solve your problem of checking if the array is all 0. 我不确定但是如果你的数组有8个字节,那么只需将基地址分配给long long变量并将其与0进行比较。这应该可以解决检查数组是否全为0的问题。

Edit 1: After Olaf's comment I would say that replace long long with int64_t . 编辑1:在奥拉夫的评论之后,我会说用int64_t替换long long However, why do you not a simple loop for iterating the array and checking. 但是,为什么不是一个简单的循环来迭代数组和检查。 8 chars is all you need to compare. 你需要比较8个字符。

Edit 2: The other approach could be to OR all elements of array and then compare with 0. If all are 0 then OR will be zero. 编辑2:另一种方法可能是对所有数组元素进行OR运算,然后与0进行比较。如果全部为0,则OR将为零。 I do not know whether CMP will be fast or OR. 我不知道CMP是快还是OR。 Please refer to Cortex-M0 docs for exact CPU cycles requirement, however, I would expect CMP to be slower. 有关精确的CPU周期要求,请参考Cortex-M0文档,但是,我希望CMP更慢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM