【问题标题】:How to assign a structure with a uin8_t array?如何使用 uin8_t 数组分配结构?
【发布时间】:2018-07-19 07:38:01
【问题描述】:

当我尝试编译以下简单代码时出现编译错误:

uint8_t latestMessageID[4];

struct Notification {
    uint8_t uuid[4];
    ...
};

Notification notificationList[NOTIFICATION_LIST_SIZE];

void setup()
{
    Notification notificationList[NOTIFICATION_LIST_SIZE];
    notificationList[0].uuid = latestMessageID; // Compilation error here
    ...
}

错误:

表达式必须是可修改的左值

Live example.

此错误的原因是什么?我该如何解决?

【问题讨论】:

  • 选择一种语言。 C 和 C++ 可能有不同的答案。例如,在 c++ 中,我们会说使用具有复制赋值运算符的 std::array
  • 一个 UUID 是 128 位(16 字节),所以这个名字有误导性

标签: c++ arrays struct


【解决方案1】:

您不能像这样分配数组。如果您实际使用 c++(和 11),则可以使用 std::array 之类的东西:

using uuid_t = std::array<uint8_t, 16>;

struct Notification {
    uuid_t uuid;
    ...

其行为完全相同,占用相同空间,但提供operator=。所以这是可能的:

notificationList[0].uuid = latestMessageID;

假设latestMessageID 也是std::array

Live example.

c++11 之前的其他选项包括 boost::array,如果您对内存分配没问题(或者即使没有并且可以提供自定义分配器),您也可以使用 std::vector

进一步说明,请注意notificationList 被声明了两次,在全局和函数setup 中。它们不是同一个对象,您在 setup 中分配的对象将在该函数结束时超出范围,您所做的更改将丢失。

【讨论】:

  • 我可以补充一下,你也可以用一个漂亮的名字来命名它,比如using uuid_t = std::array&lt;uint8_t, 4&gt;; uuid_t uuid;
  • 另外,如何让uuid 更加友好"pentium 4" 通过对齐其父级:struct alignas(16) Notification {
  • @sandthorn 我认为这超出了问题的范围。这是一个很好的建议,但可能会添加一些偏离答案的内容。
【解决方案2】:

在您的情况下,uuid 是数组类型,您不能将 分配给 数组类型。

【讨论】:

    【解决方案3】:

    您不能以这种方式复制数组:

    notificationList[0].uuid = latestMessageID;
    

    您必须复制数组的每个元素。您可以为此使用memcpy

    memcpy(notificationList[0].uuid, latestMessageID, sizeof latestMessageID);
    

    【讨论】:

    • 对于 POD 类型,memcpy() 可以。但这是复制数据的 C 方式。在 C++ 中,您应该更喜欢 std::copy()。它针对 POD 阵列进行了优化,但也适用于非 POD 阵列。
    【解决方案4】:

    因为你不能分配给数组——它们不是可修改的左值

    Notification notificationList[NOTIFICATION_LIST_SIZE];
    memcpy(notificationList[0].uuid, latestMessageID, 4);    
    

    【讨论】:

      【解决方案5】:

      你必须逐个元素地复制:

      notificationList[0].uuid[0] = latestMessageID[0];
      notificationList[0].uuid[1] = latestMessageID[1];
      notificationList[0].uuid[2] = latestMessageID[2];
      notificationList[0].uuid[3] = latestMessageID[3];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-02
        • 1970-01-01
        • 2018-09-21
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-03
        相关资源
        最近更新 更多