寻址指针中的方括号是什么?

问题描述

我一直在寻找寻址指针中的方括号,但是我仍然不理解它。下面是函数的各行,其中“ id”变量是先前已作为参数传递的uint32_t指针。

#define LIST_STARTED (0x0001) /*defined out of the function*/
#define LIST_FirsT   (0x0002) /*defined out of the function*/

uint32_t *pointer = id;
uint16_t *flags = &((uint16_t *)pointer)[0];
uint16_t *index = &((uint16_t *)pointer)[1];
bool started = *flags & LIST_STARTED;
bool first   = *flags & LIST_FirsT;

if (!started){
    /* does something */
    *flags = MSEC_PRM_MGMT_LIST_STARTED;
    return true;
}
if (!first){
    /* does something */
    *flags |= MSEC_PRM_MGMT_LIST_FirsT;
    *index = 1;
    return true;
}
if (*index == final_index)
    /* does something */
    return false;

*index += 1;

我了解该函数的逻辑是什么,但不了解以下几行的内容。我将“所有”代码放在上面,以防它对您有所帮助。

uint16_t *flags = &((uint16_t *)pointer)[0];
uint16_t *index = &((uint16_t *)pointer)[1];

如果有人可以帮助我,我将不胜感激! 谢谢!

我要说的是,这个C代码在嵌入式系统中可以正常工作,我没有修改它,我只是在观察它的行为。

解决方法

以下代码尝试将uint32_t对象读取为两个uint16_t对象的数组:

uint32_t *id = ...;
uint32_t *pointer = id;
uint16_t *flags = &((uint16_t *)pointer)[0];
uint16_t *index = &((uint16_t *)pointer)[1];

这是未定义的行为,无法通过uint32_tuint16_t指针将flags对象读取为2个index对象,因为这违反了严格的别名规则。

正确的方法是:

uint16_t flags = *id; // The lowest order bits of id.
uint16_t index = *id >> 16; // The highest order bits of id.

在上述uint32_tuint16_t的分配中,它截断了id的最高位。

,
zonecfg -z cmovel-pf01 info
zonecfg can only be run from the global zone.

它等效于

uint32_t *pointer = id;
uint16_t *flags = &((uint16_t *)pointer)[0];

定义:

uint32_t *pointer = id;
uint16_t *flags = (uint16_t *)pointer;

等同于:

uint16_t *index = &((uint16_t *)pointer)[1];

这称为:指针修剪,它被认为是危险的并且不可移植。

您可以使用联合进行安全修剪(至少在使用gcc或其衍生物时)

uint16_t *temp = (uint16_t *)pointer;
uint16_t *index = temp + 1;
//or
uint16_t *index = &temp[1];