gpt4 book ai didi

c - 从结构体访问数组并将其转换为指针

转载 作者:行者123 更新时间:2023-11-30 14:58:28 24 4
gpt4 key购买 nike

struct message {
uint8_t start;
uint16_t length;
uint8_t data[10];
uint8_t checkSum;
} __attribute__((packed));

struct message devices[10];

void request(struct message *msg) {
struct request *req = (struct request *)&msg->data;
req->operation = 1;
req->requesterAddress = MASTER_ADDRESS;
}

request(&devices[0]);

我的问题是,为什么“&msg->data”处有“&”符号?

我的理解是函数“request”接收一个指向结构的指针“msg”。 msg->data 从“msg”指向的结构中检索指针“data”(“data”是一个数组),然后将其转换为另一个指针类型(struct request *)。

所以该部分应该是 (struct request *)msg->data;那么为什么要使用&符号呢?

最佳答案

嗯,这段代码不是 C 语言,因为 __attribute__((packed))仅在 gcc 和其他一些特定实现中有效,但在标准 C 中绝对不存在。

但提供sizeof(struct message) <= 10 ,其余代码是根据 4. Conformance正确代码但包含未指定的行为,并且可能包含未定义的行为,具体取决于实现

  • request(&devices[0]);void request(struct message *msg) {...} :好的:request预计 struct message *并接收 struct message 数组的第一个元素的地址- 这里一切都很好
  • struct request *req = (struct request *)&msg->data; : 这是最有趣的部分。
    • msg->data是一个char数组,即一个聚合。聚合的地址是其第一个字节的地址。不同的说法(char *) &msg-> data (聚合的第一个字节的地址)与 msg->data 相同(数组衰减为指向其第一个元素的指针)
    • (struct request *)&msg->data;指向 char 的指针被转换为指向 struct request 的指针。根据实现的不同,没有任何东西可以保证指针正确对齐。如果不是,则根据 6.3.2.3 指针第 7 节,这是未定义的行为。如果是,根据 6.5 表达式第 6-7 节,我们仍然具有未指定的行为,因为新指针将用于存储尚未定义的元素。 char[10] 的声明类型。但这将被所有已知的实现所接受,因为它们在内部处理相同的 char 数组(显式类型)和分配的内存(没有声明的类型) - 仅仅因为它们需要实现 malloc (参见Is it possible to write a conformant implementation of malloc in C?)

其余代码没有其他问题。但需要注意的是,如果__attribute__(packed)荣幸地实现,现场data将是结构体的第三个字节,这给出了奇怪的对齐方式。这可能会导致需要对某些类型进行严格对齐的实现崩溃。

<小时/>

来自 C99 n1256 草案的引用

  1. Conformance
    ...
    2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined...
    3 A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program...

6.3.2.3 Pointers
...
7 A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object.

6.5 Expressions
...
6 The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

7 An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

  • atype compatible with the effective type of the object,
  • aqualified version of a type compatible with the effective type of the object,
  • a type that is the signed or unsigned type corresponding to the effective type of the object,
  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
  • a character type.

关于c - 从结构体访问数组并将其转换为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43332618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com