5

I am writing code for an ATSAM device using XC32 from Microchip (not clear to me if C99 or C11).

This code works fine:

typedef union {
    struct {
        uint16_t bit1 : 1;
        uint16_t bit2 : 1;
        // .. MUCH more lines...
    };
    struct {
        uint32_t data[N];
        // ... more lines, with sub-structures....
    };
} Context_t;

Context_t c;

c.data[0] = 1;
c.bit2 = false;

Notice both anonymous structures.

Since both structures are large, change all the time and their code are generated automatically by other script, it would be more convenient to use them like this:

// bit.h
typedef struct {
    uint16_t bit1 : 1;
    uint16_t bit2 : 1;
    // .. MUCH more items...
} Bits_t;

// data.h
typedef struct {
    uint32_t data[N];
    // ... more code...
} Data_t;

// import both headers
typedef union {
    Bits_t;
    Data_t;
} Context_t;

Context_t c;

c.data[0] = 1;
c.bit2 = false;

This fails to build with compiler saying declaration does not declare anything for both lines inside union. That sounds fair to me.

If I name them like bellow it works, but final code will be forced to be aware of this change in structure. Not good for our application.

typedef union {
    Bits_t b;
    Data_t d;
} Context_t;

Context_t c;

c.d.data[0] = 1;
c.b.bit2 = false;

I assume I am the culprit in here and failing example is failing due to me declaring the union the wrong way.

Any tip are welcome!

6
  • Assuming the pattern you set up always follows, why couldn't you declare an array of structs that union one uint32_t and two uint16_t values? For your uint_32 values, you could simply cast them to the desired type as needed. Commented Jan 16, 2023 at 21:49
  • Simple structure above is just to explain the issue. Actual data is very complex with thousands of lines and no regular pattern. Commented Jan 16, 2023 at 21:54
  • Well, there are ways to develop polymorphic data types in C. The trick is to know what they're going to be beforehand, as your code is not going to know about these types unless you tell it. Commented Jan 16, 2023 at 22:08
  • Structures are both complex and known!! My point is how to make then anonymous when declared externally since it work when declared in place. Commented Jan 16, 2023 at 22:20
  • If you had a typedef struct that unioned together all of your "primitive" types with an int variable that declared the actual primitive type in use, could you put them into an arbitrary-length array or linked list? Commented Jan 16, 2023 at 22:22

1 Answer 1

5

You can take advantage of the fact that include files are essentially copied-and-pasted into the source files that include them to do what you want.

If you have bit.h consist only of this:

struct {
    uint16_t bit1 : 1;
    uint16_t bit2 : 1;
    // .. MUCH more items...
};

And data.h only of this:

struct {
    uint32_t data[N];
    // ... more code...
};

Then you can create your union like this:

typedef union {
  #include "bits.h"
  #include "data.h"
} Context_t;

Allowing the two internal struct to both be anonymous and to be generated externally without having to touch the module where Context_t is defined.

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

11 Comments

That looks very unorthodox. It also looks like it might actually work. Why would one prefer this over using the actual type declarations within the union?
@RobertHarvey It allows the contents of bits.h and data.h to be externally generated. Of course, it also means that any code that uses this union needs to be aware of what's generated.
Oh, I see. Clever.
it also means that any code that uses this union needs to be aware of what's generated And that's the potential pitfall here, given the structures in question "change all the time". I'm not sure if I absolutely love or utterly detest this approach because of that. But it does solve the immediate problem.
@AndrewHenle: Since your data types are arbitrary (and not hard-coded into your application), how do you intend to define the operations that you will perform on this arbitrary data? Will that simply be a generated .c file to accompany each .h file that you generate?
|

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.