c, struct and union, struct size

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Hi guys

I find myself need to make a struct and union thing all the time like this:
Code:
    typedef struct{
        union{
            struct{
                uint32_t foo_1;
                uint32_t foo_2;
            }test_t;
            uint32_t data[2];
        };
    }foo_t;
And I find myself often need to add or remove member in a struct, and I need to change the array size manually all the time. Is there a way to automate this process?? For example:

Code:
    typedef struct{
        union{
            struct{
                uint32_t foo_1;
                uint32_t foo_2;
                // ...
                uint32_t foo_n;
            }test_t;
            uint32_t data[sizeof(foo_t)];
        };
    }foo_t;
 

BobTPH

Joined Jun 5, 2013
11,466
Yes, just make the subscript 0 in the array member. This is legal C, and since there is not subscript checking done, it will always work as long as you keep the actual subscript in range.

Bob
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Yes, just make the subscript 0 in the array member. This is legal C, and since there is not subscript checking done, it will always work as long as you keep the actual subscript in range.

Bob
So you mean like this??
Code:
    typedef struct{
        union{
            struct{
                uint32_t foo_1;
                uint32_t foo_2;
                // ...
                uint32_t foo_n;
            }test_t;
            uint32_t data[0];
        };
    }foo_t;
 

nsaspook

Joined Aug 27, 2009
16,257
Hi guys

I find myself need to make a struct and union thing all the time like this:
Code:
    typedef struct{
        union{
            struct{
                uint32_t foo_1;
                uint32_t foo_2;
            }test_t;
            uint32_t data[2];
        };
    }foo_t;
And I find myself often need to add or remove member in a struct, and I need to change the array size manually all the time. Is there a way to automate this process?? For example:

Code:
    typedef struct{
        union{
            struct{
                uint32_t foo_1;
                uint32_t foo_2;
                // ...
                uint32_t foo_n;
            }test_t;
            uint32_t data[sizeof(foo_t)];
        };
    }foo_t;
Sure, you can do that. My common practice to typedef and then create the union and other structures. Yes, I'm using structure 'tags' were they are not really needed but it's 'cleaner' to me.
https://forum.allaboutcircuits.com/threads/better-way-to-check-bit-in-c.152524/#post-1309731

C:
    typedef struct block10_type {
        uint32_t systemb;
        uint8_t bidl;
        uint8_t bidh : 7;
        uint8_t ebit : 1;
        uint8_t function;
        uint8_t stream : 7;
        uint8_t wbit : 1;
        uint8_t didl;
        uint8_t didh : 7;
        uint8_t rbit : 1;
    } block10_type;

    typedef union block10 {
        uint8_t b[sizeof(block10_type)];
        block10_type block;
    } block10;

    typedef struct header10 {
        uint16_t checksum;
        block10 block;
        uint8_t length;
    } header10;

    typedef struct header12 {
        uint16_t checksum;
        uint8_t data[2];
        block10 block;
        uint8_t length;
    } header12;


Variable creation and initialization :
C:
header12 H12[] = {
    { // S1F2 send 'yes, we are here ' from host
        .length = 12,
        .block.block.rbit = 0,
        .block.block.didh = 0,
        .block.block.didl = 0,
        .block.block.wbit = 0,
        .block.block.stream = 1,
        .block.block.function = 2,
        .block.block.ebit = 1,
        .block.block.bidh = 0,
        .block.block.bidl = 1,
        .block.block.systemb = 1,
        .data[1] = 1,
        .data[0] = 0,
    },
    { // S1F13 send 'online request ' from host to equipment
        .length = 12,
        .block.block.rbit = 0,
        .block.block.didh = 0,
        .block.block.didl = 0,
        .block.block.wbit = 1,
        .block.block.stream = 1,
        .block.block.function = 13,
        .block.block.ebit = 1,
        .block.block.bidh = 0,
        .block.block.bidl = 1,
        .block.block.systemb = 1,
        .data[1] = 1,
        .data[0] = 0,
    },
};
 
Last edited:

Thread Starter

bug13

Joined Feb 13, 2012
2,002
I think it should be:
  • uint32_t data[sizeof(test_t)/sizeof(uint32_t)];
I tested in code::block, it doesn't compile:

||=== Build: Debug in test_func (compiler: GNU GCC Compiler) ===|
D:\Desktop\New folder\test_func\main.c|14|error: 'test_t' undeclared here (not in a function)|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Code:
#include <stdio.h>
#include <stdint-gcc.h>


typedef struct
{
    union
    {
        struct
        {
            uint32_t foo_1;
            uint32_t foo_2;
        } test_t;
        uint32_t data[sizeof(test_t)/sizeof(uint32_t)];
    };
} foo_t;

int main()
{
    return 0;
}
 

MrSoftware

Joined Oct 29, 2013
2,273
I tested in code::block, it doesn't compile:

||=== Build: Debug in test_func (compiler: GNU GCC Compiler) ===|
D:\Desktop\New folder\test_func\main.c|14|error: 'test_t' undeclared here (not in a function)|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Code:
#include <stdio.h>
#include <stdint-gcc.h>


typedef struct
{
    union
    {
        struct
        {
            uint32_t foo_1;
            uint32_t foo_2;
        } test_t;
        uint32_t data[sizeof(test_t)/sizeof(uint32_t)];
    };
} foo_t;

int main()
{
    return 0;
}

You need to define your test_t type before you build the union.

Code:
typedef struct test_t
{
    uint32_t foo_1;
    uint32_t foo_2;
}test_t;

    union foo_t
    {
        test_t Test_T;
        uint32_t data[sizeof(test_t) / sizeof(uint32_t)];
    };
 
Last edited:
Top