assigning values to struct from const

Hi all -

I'm porting a project that has some rather unusual coding. I have a struct -- actually an array of structs, that needs to be populated. The original programmer defined the initialization values like this:

#define DEFAULT_SCHEDULE {0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x53, 0x63,\
0x68, 0x65, 0x64, 0x75, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0xFE, 0x02,\
0xA4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\

(I know this is ridiculous, but this is how he did it.)

Is there any clean way to assign this mess to the array of structs?

Thanks...
Last edited on
You have not shown the declaration of the structs, so can't make specific recommendations.
Last edited on
Hi AbstractionAnon -

I was hoping that it wouldn't matter (looking for a universal solution here), but let's say the struct is something like this:

typedef struct
{
char label[34];
uint8_t start_hour;
uint8_t start_minute;
uint8_t stop_hour;
uint8_t stop_minute;
uint8_t dayofweek; // bit 1 = sunday.... bit 7 = saturday
uint8_t active; // 0 = uninitialized, 1 = enabled, 2 = disabled
int16_t rpm;
} schedule_span_t;
Presumably, each element in the "DEFAULT_SCHEDULE" will only be a byte large, and the struct only contains "POD" data (i.e. no pointers). You could store this data into an unsigned char array, and then memcpy into the array of structs. This assumes that the data being copied actually lines up with the bytes of each struct; there can be padding to the struct layout, which the compiler internally determines, so 'solutions' like these are inherently hackish and fragile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <cstdint>
#include <cstring>

using namespace std;

#define DEFAULT_SCHEDULE {0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x53, 0x63,\
0x68, 0x65, 0x64, 0x75, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0xFE, 0x02,\
0xA4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00}
//Note: Bytes were added to make length of data a multiple of sizeof(struct)

typedef struct
{
    char label[34];
    uint8_t start_hour;
    uint8_t start_minute;
    uint8_t stop_hour;
    uint8_t stop_minute;
    uint8_t dayofweek; // bit 1 = sunday.... bit 7 = saturday
    uint8_t active; // 0 = uninitialized, 1 = enabled, 2 = disabled
    int16_t rpm;
} schedule_span_t;


int main()
{
    unsigned char data[] = DEFAULT_SCHEDULE;
    std::cout << "sizeof(data): " << sizeof(data) << '\n';
    std::cout << "sizeof(schedule_span_t): " << sizeof(schedule_span_t) << '\n';
    
    schedule_span_t arr[2];
    std::cout << "sizeof(schedule_span_t arr[2]): " << sizeof(arr) << '\n';
    
    memcpy(arr, data, sizeof(arr));
    
    for (int i = 0; i < 2; i++)
    {
        bool null_terminated = false;
        for (int j = 0; j < 34; j++)
        {
            if (arr[i].label[j] == '\0')
            {
                null_terminated = true;
                break;
            }
        }
        
        if (null_terminated)
        {
            std::cout << "Label " << i << ": \"" << arr[i].label <<  "\"\n";
        }
        else
        {
            std::cout << "Warning: Label " << i << " is not properly null-terminated\n";
        }
    }

}

sizeof(data): 84
sizeof(schedule_span_t): 42
sizeof(schedule_span_t arr[2]): 84
Label 0: "Default Schedule"
Label 1: ""
Last edited on
There's also big/little endian coming into play as well (int16_t).

Please, please don't initialise like this.

Also consider a sanity check:

 
static_assert(sizeof(data) % sizeof(schedule_span_t)) == 0);


which could detect padding.
Topic archived. No new replies allowed.