3

I have such struct

struct hour_parameters{
    uint8_t VALUE_00;
    uint8_t VALUE_01;
    uint8_t VALUE_02;
    uint8_t VALUE_03;
    uint8_t VALUE_04;
    uint8_t VALUE_05;
    uint8_t VALUE_06;
    uint8_t VALUE_07;
    uint8_t VALUE_08;
    uint8_t VALUE_09;
    uint8_t VALUE_10;
    uint8_t VALUE_11;
    uint8_t VALUE_12;
    uint8_t VALUE_13;
    uint8_t VALUE_14;
    uint8_t VALUE_15;
    uint8_t VALUE_16;
    uint8_t VALUE_17;
    uint8_t VALUE_18;
    uint8_t VALUE_19;
    uint8_t VALUE_20;
    uint8_t VALUE_21;
    uint8_t VALUE_22;
    uint8_t VALUE_23;
};

struct hour_parameters hparam;

I would like to assign an uint8_t x[24] hparam, how can I do it with a for loop, that

hparam.value00 = x[0];
hparam.value01 = x[1];
and so on?
4
  • 3
    Why don't you use an array? Commented Oct 26, 2013 at 21:57
  • yes it may seem better to use array for the above example. But I just wanted to make an example as simple as possible. Sometimes, it is more convenient and readable to use struct. I just wonder how the assignment could be done in struct Commented Oct 26, 2013 at 22:02
  • 1
    I meant use an array inside your struct. Commented Oct 26, 2013 at 22:04
  • Are you asking how to write a loop?! Commented Oct 26, 2013 at 22:05

4 Answers 4

4

You really should use an array in your struct but....

#include <string.h>
memcpy(&hparam, x, sizeof(hparam));

( I'm ducking under the table now )

One the reasons this is dangerous is possible padding in the struct. Now, since they are all bytes, you are pretty safe. But, technically, this kind of stuff is not legal. One thing you could do before hand is

assert(sizeof(hparam) == sizeof(x));

If you insist on a for loop:

for(int i = 0; i != sizeof(hparam); i++) {
    ((uint8_t *)&hparam)[i] = x[i];
}

Which is ugly and not too kosher either. Kerrek's comments below present reasons not to do this.

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

1 Comment

Padding is not so far-fetched. The C11 memory model mandates that all struct members can be modified individually without inventing writes to other variables, so an architecture that doesn't have byte-wide memory access may well need to use padding (or not have a uint8_t).
1

As @Charlie Burns pointed out, you want to try and avoid it unless you know exactly how the structures are padded/aligned. Its not portable coding style.

You could also do a struct assignment such as

hparams = *(struct hour_parameters *)x;

Comments

1

As Charlie Burns says, you can use this struct as an array, for safety, force the maximum alignment of members to 1 if your compiler supports pragma pack

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#pragma pack(push,1)
struct hour_parameters{
    uint8_t VALUE_00;
    uint8_t VALUE_01;
    uint8_t VALUE_02;
    uint8_t VALUE_03;
    ...
};
#pragma pack(pop)

int main(void)
{
    struct hour_parameters hparam;
    uint8_t x[24] = {0};

    memcpy(&hparam, x, 24);
    printf("%u\n", hparam.VALUE_12);
    return 0;
}

Comments

1

This should work:

memcpy_s( &hparam, sizeof hparam, x, sizeof x )

Though this is not good code.

Note that your struct is equivalent to array, so better solution is:

uint8_t hparam[24] = {0};
memcpy_s( hparam, sizeof hparam, x, sizeof x );

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.