1

I have a compilation error when i attempt to compile the following simple code:

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
    ...
}

Error:

expression must be a modifiable lvalue

Live example.

What is the cause of this error and how can i approach a solution?

2
  • Choose a language. C and C++ may have different answers. For example, in c++ we would say use a std::array which has a copy assignment operator. Commented Jul 19, 2018 at 7:42
  • 2
    A UUID is 128-bit (16 byte) so this name is misleading Commented Jul 19, 2018 at 8:10

5 Answers 5

4

You cannot assign an array like this. If you are actually using c++ (and 11) you can utilize something like std::array:

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

struct Notification {
    uuid_t uuid;
    ...

Which acts exactly the same, occupies the same space, but provides an operator=. So this would be possible:

notificationList[0].uuid = latestMessageID;

Assuming latestMessageID is also a std::array

Live example.

Other options for pre-c++11 include boost::array and if you are ok with memory allocation (or even if not and can provide a custom allocator) you could use std::vector.

As a further note, be aware that the notificationList is declared twice, globally and in the function setup. These are not the same object, and the one that you are assigning to in setup will go out of scope at the end of that function and the changes you made will be lost.

Sign up to request clarification or add additional context in comments.

3 Comments

May i add that you can also name it with a pretty name like using uuid_t = std::array<uint8_t, 4>; uuid_t uuid;
In additions, how about make uuid more "pentium 4" friendly by align its parent :struct alignas(16) Notification {.
@sandthorn I think that is outside the scope of the question. It is a good suggestion, but maybe will add fluff that draws away from the point of the answer.
1

In your case, uuid is an array type, you cannot assign to an array type.

Comments

1

You cannot copy an array this way:

notificationList[0].uuid = latestMessageID;

You must copy each element of the array. You can use memcpy for that:

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

1 Comment

For POD types, memcpy() is OK. But that is the C way to copy data. In C++, you should prefer std::copy() instead. It is optimized for POD arrays, but also works for non-POD arrays too.
0

Because you can't assign to arrays -- they're not modifiable l-values

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

Comments

0

You had to copy element by element:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.