Create a struct in C Preprocessor - c

Right now, I am writing a small project in C to test out some serialization techniques.
One way that I am doing this is through the use of unions. Something that I would like to try is creating a union in the C preprocessor that holds a user-defined structure. For example, something like this:
#define create_union(name_of_structure, type_of_structure) \
\
typedef union name_of_structure { \
typeof(type_of_structure) structure; \
char buffer_that_holds_structure[sizeof(type_of_structure)]; \
} name_of_structure;
/* Usage */
struct my_data {
int id;
int other_value;
};
create_union(my_data_t, struct my_data);
/* Data type my_data_t (union my_data_t) now exists */
First of all, is this feasible? If it is, how would I go about doing this? If not, is there an alternative method I can use?
Thanks!

Yes, it's possible, and your code is very close to correct.
I'd drop the semicolon at the end of the macro definition. I'd also drop the use of typeof; it's not portable and it's not needed unless you want to use an expression, rather than a type name, as the first argument to create_union.
Here's how I'd probably define it. (I don't bother with typedefs for struct or union types; I just use the name struct foo or union foo unless the type is intended to be completely opaque. Feel free to use the typedef if you prefer.) (I've also used unsigned char rather than char, since that's how object representations are defined.)
#define CREATE_UNION(new_type, existing_type) \
union new_type { \
existing_type obj; \
unsigned char rep[sizeof(existing_type)]; \
}
And you can then do:
CREATE_UNION(int_wrapper, int);
int_wrapper foo;
Note that what you're defining is a union, not a structure.

Related

Can you declare an anonymous instance of a named struct?

I'm trying to manually implement a polymorphic behavior in C by creating a generic struct, and then derived structs (if you will) which can be told apart by the value of an enum, so that I can have a pointer to the generic type, dereference it as the generic type, figure out what type it is, and then dereference it as the more specific type.
typedef struct{
enum type structType;
//... other stuff all the structs share
}generic;
typedef struct{
generic; //does not work, obviously, nor does (generic){};
//... other stuff unique to struct type A
}typeA;
I understand that I could just declare a named instance of the generic struct in the derived struct, but this seems a little messy, and I would prefer not to if there's a neat and tidy way around it.
You can't always get what you want, but if you try sometimes, well, you might find, you get what you need ...
There are two basic ways, with a slight bit of trickery:
Using an include file (e.g.): generic.h
Using a CPP macro (e.g): GENERIC
I've used both methods at various times.
Here's the method with the include file (generic.h):
enum type structType;
int com_fd;
void *com_buf;
And, here's a .c file that uses it:
typedef struct {
#include <generic.h>
} generic;
typedef struct {
#include <generic.h>
// other stuff unique to struct type A ...
int typea_value;
} typeA;
Here's the method using a macro:
#define GENERIC \
enum type structType; \
int com_fd; \
void *com_buf
typedef struct {
GENERIC;
} generic;
typedef struct {
GENERIC;
// other stuff unique to struct type A ...
int typea_value;
} typeA;
Can you declare an anonymous instance of a named struct?
No.
Yet code can make-up a name based on the line number, to keep it unique and with some level of animosity.
Now code should not try to reference var.member11 as the member's name changes as the code for typeA definition moves about in the file.
#define ANON_1(A,B) A##B
#define ANON_2(A,B) ANON_1(A,B)
#define ANON ANON_2(member, __LINE__)
typedef struct{
int x;
} generic;
typedef struct{
generic ANON; // name will be something like: member10
generic ANON; // name will be something like: member11
int y;
} typeA;
int main() {
typeA var;
(void) var;
return 0;
}
I suspect though to achieve OP's higher goal, a better approach is possible.

What is the rationale behind using an union in DECLARE_KFIFO

I am looking at the <linux/kfifo.h>, specifically the DECLARE_KFIFO macro, and I can't figure out why use an union.
#define DECLARE_KFIFO(name, size) \
union { \
struct kfifo name; \
unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \
}
My questions are as follows:
What is the point of using an union over here ? What design goal does that solve ? Is it for performance reasons ?
How would you even access this anonymous union ? For example this does not work:
#include <stdio.h>
int main()
{
union {
int a;
float b;
};
a = 10;
}
main.c:18:5: error: ‘a’ undeclared (first use in this function)
a = 10;
^
Why declare something that cannot be used ?
How does this work with the INIT_KFIFO macro ? How is able to access the union and what relation does it have with the previous macro ?
If my memory serves me correctly, then in C you can only use one one element in an union. So what is going on here ? It will just use one member from the declared union ?
Note: This code is for the 2.6.33 kernel. I know its old code, but the recent kernel 5.6.12 still uses a union in kfifo, only its a lot more complicated.
The comments to the macro explain almost everything:
/**
* DECLARE_KFIFO - macro to declare a kfifo and the associated buffer
* #name: name of the declared kfifo datatype
* #size: size of the fifo buffer. Must be a power of two.
*
* Note1: the macro can be used inside struct or union declaration
* Note2: the macro creates two objects:
* A kfifo object with the given name and a buffer for the kfifo
* object named name##kfifo_buffer
*/
This macro is used only as a (some other) structure's or union's field. With such usage the macro creates(allocates in the structure or in the union):
a kfifo object which can be accessed as a field with the name name and
a buffer for kfifo.
So, structure declaration like
struct my_struct {
int a;
char b;
DECLARE_KFIFO(my_fifo, 100);
};
gives similar effect as
struct my_struct {
int a;
char b;
// This field may be used for call kfifo functions
struct kfifo my_fifo;
// This field is never used directly.
// Pointer to this buffer is stored in the '.buffer' field of kfifo object.
unsigned char buffer_internal_to_kfifo_implementation[size];
};
It would be more natural for declaring two objects to use a anonymous structure of two fields instead of union:
#define DECLARE_KFIFO(name, size) \
struct { \
struct kfifo name; \
unsigned char name##kfifo_buffer[size]; \
}
It should be exactly anonymous for allow direct access to its name field.
Compared to structure's implementation, actual implementation of DECLARE_KFIFO via anonymous union gives the same "field" name and allocates the same amount of bytes (of number size) for its buffer:
union { \
struct kfifo name; \
unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \
}
It is difficult to say why they choose union instead of struct.
the recent kernel 5.6.12 still uses a union in kfifo, only its a lot more complicated.
Not quite true. The newer kernel versions uses union for absolutely different purposes:
#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
union { \
struct __kfifo kfifo; \
datatype *type; \
const datatype *const_type; \
char (*rectype)[recsize]; \
ptrtype *ptr; \
ptrtype const *ptr_const; \
}
Here kfifo is the only field which is accessed for write/read bytes of data. All other fields are declared just for extract their types using typeof() operator.
So, __STRUCT_KFIFO_COMMON is just a "clever" struct kfifo declaration which knows types of data it contains.
Definition of DECLARE_KFIFO macro
#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
after expanding intermediate macros gives:
#define DECLARE_KFIFO(fifo, type, size) struct { \
__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
} fifo
So that time it is a field of the structure type with the given name. Similar to the old definition, this structure contain two fields:
struct kfifo object (its "clever" version) and
a buffer for kfifo.

sizeof anonymous nested struct

Suppose I have structure I'm using to model various packet formats:
#define MaxPacket 20
typedef struct {
u8 packetLength;
union {
u8 bytes[MaxPacket];
struct {
u16 field1;
u16 field2;
u16 field3;
} format1;
struct {
double value1;
double value2;
} format2;
};
} Packet;
I can expect that sizeof(Packet) will be 21. But is there any way to do something like:
sizeof(Packet.format2)
? I've tried that, but the compiler is not happy. Obviously, I could pull the format1 out as a separate typedef and then I could sizeof(format1). But I'm curious if I have to through all of that. I like the hierarchical composition of the formats. This is with gcc on an 8bit processor.
I'm equally interested if there's a way to use the nested type. IF I have to do a lot of
aPacketPointer->format2.value1; // not so onerous, but if the nesting gets deeper...
Then sometimes it would be nice to do:
Packet.format2 *formatPtr = &aPacketPointer->format2;
formatPtr->value2; // etc
Again, refactoring into a bunch of preceding typedefs would solve this problem, but then I lose the nice namespacing effect of the nested dotted references.
For something that will work even in C90, you can use a macro modeled on your toolchain's offsetof() macro:
#define sizeof_field(s,m) (sizeof((((s*)0)->m)))
Adjust it accordingly if your toolchain's offsetof() macro isn't based on casting 0 to a pointer to the structure's type.
When I use it like so:
std::cout << sizeof_field(Packet,format1) << std::endl;
std::cout << sizeof_field(Packet,format2) << std::endl;
I get the output:
6
16
For your second question, if you're willing to rely on GCC's typeof extension you can create a similar macro for declaring pointers to your nested anonymous structs:
#define typeof_field(s,m) typeof(((s*)0)->m)
...
typeof_field(Packet,format2)* f2 = &foo.format2;
To be honest, I find that construct pretty ugly, but it might still be better than other options you have available.
GCC documents that the "operand of typeof is evaluated for its side effects if and only if it is an expression of variably modified type or the name of such a type", so the apparent null pointer deference should not result in undefined behavior when a variable length array is not involved.
Using C11 or C99, create a dummy compound literal and seek its size.
printf("%zu\n", sizeof( ((Packet){ 0, { "" }}).format2 ));
Output
16
You can just give those nested structs a name, no need for a typedef. Like this:
typedef struct {
u8 packetLength;
union {
u8 bytes[MaxPacket];
struct myformat1 {
u16 field1;
u16 field2;
u16 field3;
} format1;
struct myformat2 {
double value1;
double value2;
} format2;
};
} Packet;
Then you can write e.g. sizeof(struct myformat1), declare variables of that type, etc.
You could also add a typedef afterwards, e.g.
typedef struct myformat1 myformat1;

Compile time check polymorphic types in C?

Polymorphic structs are quite common in C but often involve explicit casts which allow for accidentally casting incompatible structs.
struct ID {
char name[32];
};
struct IntID {
struct ID id_base;
int value;
}
struct FloatID {
struct ID id_base;
float value;
}
void id_name_set(ID *id, const char *name)
{
strlcpy(id->name, name, sizeof(id->name));
}
/* macro that happens to use 'id_name_set', this is a bit contrived */
#define ID_NAME_SET_AND_VALUE(id, name, val) \
do { \
id_name_set((ID *)id, name); \
id->value = val; \
} while(0)
void func(void)
{
struct { int value; } not_an_id;
/* this can crash because NotID doesn't have an ID as its first member */
ID_NAME_SET_AND_VALUE(not_an_id, "name", 10);
}
The issue here is we can't type check the id argument in the macro against a single type, since it could be an ID or any struct with an ID as its first member.
A lot of code I've seen simply casts to the struct all over the place, but it seems it is possible to have a more reliable method.
Is there a way to check at compile time?
Note, for the purpose of this question, we can assume all structs use the same member name for the struct they inherit from.
Note, I was hoping to be able to use something like this...
# define CHECK_TYPE_POLYMORPHIC(val, member, struct_name) \
(void)(_Generic((*(val)), \
/* base-struct */ struct_name: 0, \
/* sub-struct */ default: (_Generic(((val)->member), struct_name: 0))))
/* --- snip --- */
/* check that `var` is an `ID`, or `var->id_base` is */
CHECK_TYPE_POLYMORPHIC(var, id_base, ID);
...but this fails for ID types in the default case - because they have no id member.
So far the only way I found to do this is to type-check against a complete list of all structs, which isn't ideal in some cases (may be many — or defined locally, therefore not known to the macro, see: Compile time check against multiple types in C?).
You shouldn't use casts. A cast supposes that you know what you are doing and in the worst case leads to undefined behavior. You'd have to rely on the fact that the types that you are interested in all have that struct ID field with the same name.
Then, in the case that you present where you actually have a do-while kind of functional macro, you can easily place an auxiliary variable:
#define ID_NAME_SET_AND_VALUE(id, name, val) \
do { \
ID* _id = &((id)->id_base)); \
id_name_set(_id, (name)); \
_id->value = (val); \
} while(0)
If all goes well, this is a nop, if not it is a constraint violation and aborts compilation.
In a context where you can't place a variable you could use a compound literal, something like
(ID*){ &((id)->id_base)) }
The closest thing in C11 (the latest C standard) for compile-time polymorphism is its
type-generic expressions using the _Generic keyword, but I am not sure it fits your needs.
The GCC compiler also gives you its __builtin_type_compatible_p with which you could build e.g. some macros.
You could also customize GCC with some MELT extensions

Way to shorten struct *pointerexample so that I don't have to type it out?

I remember my professor showed us how to replace a "struct" statement such as struct *pointerexample so that we do not have to type it out each time. However, I don't remember if they used a preprocessor directive such as #define or how they did it. Any ideas? Also, how would I do #define EXAMPLE struct *pointerexample? Is that the correct way?
Use a typedef:
struct pointerexample {};
typedef struct pointerexample *ppe;
With this, you can use ppe to create pointers to pointerexample:
ppe var1, var2;
A common approach is to first use a typedef to reduce the amount of typing when declaring a struct. This allows you to just use a named type rather than having to use the struct keyword everywhere. eg:
typedef struct myStruct {
int a;
char c;
} myStruct_t;
myStruct_t aStruct; // Declare a struct
aStruct.a = 0; // Set a to zero
myStruct_t* pS = &aStruct; // Pointer to a struct
pS->a=1; // Set a to one
typedef struct pointerexample SPE, * PSPE;
Now you can use SPE instead of the longish name. And better do not use PSPE as a pointer to the latter, as this is close to obsfucating code, in my opinion.
Using the pre-processor would do also:
#define SPE struct pointerexample
However this latter approach could lead to unexpected results under certain conditions. There is no need to use the pre-processor here, as there is the former solution.

Resources