Macro for struct members - c

I have a struct definition that I am not allowed to change. However, I would like to access a member after doing an operation on it (the operator appears after the first operand). It occurred to me that I could use a macro to access the modified value as if it were part of the struct itself.
struct test{
int a;
int b;
} *t;
#define c b+1
...
printf("%d", t -> c);
This does look nicer to me, but it feels like something could go wrong with replacement. Is there a better way to do something like this? Is this bad practice? What can go wrong?

What can go wrong?
printf("%d", t->c * 3);
For starters.

Your suggestion is bad.
Single letter members and macros (but let's ignore that)
Hard to read and support. (is t->c a member or one of those crazy marcros I added? Was c +1 or -1?
If you really have to macro-ize it for some reason, then make it clearer.
e.g.
#define BPlusOne(t) ((t)->b + 1)
printf("%d", BPlusOne(t));
If it's just a simple piece of work for school this is overkill, but I'm currently working on a big system where the structs are generated as are all of these type of macros, and in this case it works (but I still wouldn'thave done it this way ;-)

Related

What does (std::size_t)&((Structure *)0)->last do?

I recently came across this code and thought it was a little overkill.
struct Structure {
unsigned int first;
unsigned int last;
};
(std::size_t)&((Structure *)0)->last; // 4
So I'm wondering if I can safely do:
sizeof(unsigned int); // 4
instead of:
(std::size_t)&((Structure *)0)->last; // 4
or what that code is doing anyway if it's so much better.
EDIT
That code more or less euqals to offsetof as pointed out in https://stackoverflow.com/a/1379370/1001563
If you know what you're searching for you'll find the answer without having to ask. Thanks to #VladfromMoscow
Programs are usually being changed. So it is better to use a general approach. For example the type of data member first can be changed or before data member last there can be added one more data member.
Take into accpunt that there is already a similar macro in C defined in <stddef.h> (or <cstddef> in C++)
offsetof(type, member-designator)

Will this trick work in C?

I want to add a field to a structure in C. So for example I have the following structure.
struct A
{
some_type x;
some_type y;
}
I declare a new structure, like this.
struct B
{
A a;
some_type z;
}
Now say I have a function like this.
int some_function( A * a )
Is it possible to pass a variable of type B to it like this in the program.
B * b;
......
A * a = (A*)b;
some_function( a );
And also be able to use the fields inside some_function by using a->x for example?
Yes, it is valid. Word of the Standard, C99 6.7.2.1/13:
... A pointer to a
structure object, suitably converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa. There may be unnamed
padding within a structure object, but not at its beginning.
Yes, it would work. A a will be the first member in the struct
This is how some people simulated OO inheritance in C
You may use
&b->a
instead of the cast.
And probably do an ASSERT like
ASSERT (&b->a == b)
to be warned when you accidentally destroyed this semantic
Why not just call the method on the member?
some_function( &b->a );
Your code works now, but what if somebody decides to change the members of B? Or add a new member before a?
Yes, this would work, but only by accident.
If I recall the C99 standard correctly, this particular case is specifically required to work as you expect. But it's clear that this is only because sufficiently many people relied on it working before that, and it did work by accident in sufficiently many implementations, that the C99 standards committee felt obliged to legislate for it working de jure as well as de facto.
Don't let that tempt you into thinking that this is a good idea.
Anything which relies on standards edge-cases is permanently teetering on the edge of brokenness, because it looks hacky (and so makes your code's future readers uncomfortable) and looks clever (which makes them nervous of changing/fixing anything). Also it leads folk into making assumptions which, because you're already on the edge of what's legitimate, can tempt folk across the border into broken code. For example, the fact that the first element within the first sub-struct within a struct is aligned as you expect, does not imply that any other sub-elements are lined up. That fact that it works for your compiler does not imply that it'll work for anyone else's, leading to mind-bendingly confusing bugs.
Write:
A *a = &(b->a);
(as the comment above suggests) and your meaning is clear.
If for some obscure reason you have to cast B* to A*, then write a very clear comment explaining why you have no option but to do what you have to do, assuring the reader that it is legitimate, and pointing to the subsubsection of the C99 standard which licenses it.
If you really cannot find that subsection (and finding it is your homework/penance), then comment thus and I'll dig it up.
No it won't work. It would work if you change it a bit:
struct A
{
some_type x;
some_type y;
}; /* <- note semicolon here */
struct B
{
struct A a;
some_type z;
}; /* ... and here */
int some_function(struct A *a ); /* ... and here ... */
struct B *b;
......
struct A *a = (struct A*)b;
some_function( a );

Which way is better for creating type-agnostic structures in C?

I'm trying to write some generic structures. Essentially, what I need for my purpose is C++ templates, but since I'm writing in C, templates are out of consideration. Currently I'm considering 2 ways of achieving what I want.
Method 1: use the preprocessor. Like so:
#define DEFINE_PAIR(T) typedef struct Pair_##T{ \
T x; \
T y; \
} Pair_##T
DEFINE_PAIR(int);
int main(){
Pair_int p;
return 0;
}
An obvious downside to it is that you have to invoke the macro before using the type. Probably there are more disadvantages, which I hope you will point out.
Method 2: just use void-pointers, like so:
typedef struct Pair{
void* x;
void* y;
} Pair;
Obviously, this approach is not type safe (I could easily pass a pair of strings to a function expecting a pair of doubles), plus the code doing deallocation gets a lot messier with this approach.
I would like to hear your thoughts on this. Which of the two methods is better/worse and why? Is there any other method I could use to write generic structures in C?
Thanks.
If you only plan on using primitive data types, then your original macro-based solution seems nifty enough. However, when you start storing pairs of pointers to opaque data types with complex structures underneath that are meant to be used by passing pointers between functions, such as:
complex_structure_type *object = complex_structure_type_init();
complex_structure_type_set_title(object, "Whatever");
complex_structure_type_free(object);
then you have to
typedef complex_structure_type *complex_structure_type_ptr;
in order to
DEFINE_PAIR(complex_structure_type_ptr);
so you can
Pair_complex_structure_type_ptr p;
and then
p.x = object;
But that's only a little bit more work, so if you feel it works for you, go for it. You might even put together your own preprocessor that goes through the code, pulls out anything like Pair_whatever, and then adds DEFINE_PAIR(whatever) for the C preprocessor. Anyway, it's definitely a neat idea that you've presented here.
Personally, I would just use void pointers and forget about strong type safety. C just doesn't have the same type safety machinery as other languages, and the more opportunities you give yourself to forget something, the more bugs you'll accidentally create.
Good luck!
Noting that templates in c++ provide a language for writing code, you might simple consider doing code generation with some tool more powerful than the c-preprocessor.
Now that does add another step to you build, and makes you build depend on another toll (unless you care to write your own generator in c...), but it may provide the flexibility and type-safety you desire.
This is almost the same, but it's a bit more nimble:
#define PAIR_T(TYPE) \
struct { \
TYPE x; \
TYPE y; \
}
typedef PAIR_T(int) int_pair;
typedef PAIR_T(const char *) string_pair;
int main(void)
{
int_pair p = {1, 1};
string_pair sp = {"a", "b"};
}

Access struct members as if they are a single array?

I have two structures, with values that should compute a pondered average, like this simplified version:
typedef struct
{
int v_move, v_read, v_suck, v_flush, v_nop, v_call;
} values;
typedef struct
{
int qtt_move, qtt_read, qtt_suck, qtd_flush, qtd_nop, qtt_call;
} quantities;
And then I use them to calculate:
average = v_move*qtt_move + v_read*qtt_read + v_suck*qtt_suck + v_flush*qtd_flush + v_nop*qtd_nop + v_call*qtt_call;
Every now and them I need to include another variable. Now, for instance, I need to include v_clean and qtt_clean. I can't change the structures to arrays:
typedef struct
{
int v[6];
} values;
typedef struct
{
int qtt[6];
} quantities;
That would simplify a lot my work, but they are part of an API that need the variable names to be clear.
So, I'm looking for a way to access the members of that structures, maybe using sizeof(), so I can treat them as an array, but still keep the API unchangeable. It is guaranteed that all values are int, but I can't guarantee the size of an int.
Writing the question came to my mind... Can a union do the job? Is there another clever way to automatize the task of adding another member?
Thanks,
Beco
What you are trying to do is not possible to do in any elegant way. It is not possible to reliably access consecutive struct members as an array. The currently accepted answer is a hack, not a solution.
The proper solution would be to switch to an array, regardless of how much work it is going to require. If you use enum constants for array indexing (as #digEmAll suggested in his now-deleted answer), the names and the code will be as clear as what you have now.
If you still don't want to or can't switch to an array, the only more-or-less acceptable way to do what you are trying to do is to create an "index-array" or "map-array" (see below). C++ has a dedicated language feature that helps one to implement it elegantly - pointers-to-members. In C you are forced to emulate that C++ feature using offsetof macro
static const size_t values_offsets[] = {
offsetof(values, v_move),
offsetof(values, v_read),
offsetof(values, v_suck),
/* and so on */
};
static const size_t quantities_offsets[] = {
offsetof(quantities, qtt_move),
offsetof(quantities, qtt_read),
offsetof(quantities, qtt_suck),
/* and so on */
};
And if now you are given
values v;
quantities q;
and index
int i;
you can generate the pointers to individual fields as
int *pvalue = (int *) ((char *) &v + values_offsets[i]);
int *pquantity = (int *) ((char *) &q + quantities_offsets[i]);
*pvalue += *pquantity;
Of course, you can now iterate over i in any way you want. This is also far from being elegant, but at least it bears some degree of reliability and validity, as opposed to any ugly hack. The whole thing can be made to look more elegantly by wrapping the repetitive pieces into appropriately named functions/macros.
If all members a guaranteed to be of type int you can use a pointer to int and increment it:
int *value = &(values.v_move);
int *quantity = &(quantities.qtt_move);
int i;
average = 0;
// although it should work, a good practice many times IMHO is to add a null as the last member in struct and change the condition to quantity[i] != null.
for (i = 0; i < sizeof(quantities) / sizeof(*quantity); i++)
average += values[i] * quantity[i];
(Since the order of members in a struct is guaranteed to be as declared)
Writing the question came to my mind... Can a union do the job? Is there another clever way to automatize the task of adding another member?
Yes, a union can certainly do the job:
union
{
values v; /* As defined by OP */
int array[6];
} u;
You can use a pointer to u.values in your API, and work with u.array in your code.
Personally, I think that all the other answers break the rule of least surprise. When I see a plain struct definition, I assume that the structure will be access using normal access methods. With a union, it's clear that the application will access it in special ways, which prompts me to pay extra attention to the code.
It really sounds as if this should have been an array since the beggining, with accessor methods or macros enabling you to still use pretty names like move, read, etc. However, as you mentioned, this isn't feasible due to API breakage.
The two solutions that come to my mind are:
Use a compiler specific directive to ensure that your struct is packed (and thus, that casting it to an array is safe)
Evil macro black magic.
How about using __attribute__((packed)) if you are using gcc?
So you could declare your structures as:
typedef struct
{
int v_move, v_read, v_suck, v_flush, v_nop, v_call;
} __attribute__((packed)) values;
typedef struct
{
int qtt_move, qtt_read, qtt_suck, qtd_flush, qtd_nop, qtt_call;
} __attribute__((packed)) quantities;
According to the gcc manual, your structures will then use the minimum amount of memory possible for storing the structure, omitting any padding that might have normally been there. The only issue would then be to determine the sizeof(int) on your platform which could be done through either some compiler macros or using <stdint.h>.
One more thing is that there will be a performance penalty for unpacking and re-packing the structure when it needs to be accessed and then stored back into memory. But at least you can be assured then that the layout is consistent, and it could be accessed like an array using a cast to a pointer type like you were wanting (i.e., you won't have to worry about padding messing up the pointer offsets).
Thanks,
Jason
this problem is common, and has been solved in many ways in the past. None of them is completely safe or clean. It depends on your particuar application. Here's a list of possible solutions:
1) You can redefine your structures so fields become array elements, and use macros to map each particular element as if it was a structure field. E.g:
struct values { varray[6]; };
#define v_read varray[1]
The disadvantage of this approach is that most debuggers don't understand macros. Another problem is that in theory a compiler could choose a different alignment for the original structure and the redefined one, so the binary compatibility is not guaranted.
2) Count on the compiler's behaviour and treat all the fields as it they were array fields (oops, while I was writing this, someone else wrote the same - +1 for him)
3) create a static array of element offsets (initialized at startup) and use them to "map" the elements. It's quite tricky, and not so fast, but has the advantage that it's independent of the actual disposition of the field in the structure. Example (incomplete, just for clarification):
int positions[10];
position[0] = ((char *)(&((values*)NULL)->v_move)-(char *)NULL);
position[1] = ((char *)(&((values*)NULL)->v_read)-(char *)NULL);
//...
values *v = ...;
int vread;
vread = *(int *)(((char *)v)+position[1]);
Ok, not at all simple. Macros like "offsetof" may help in this case.

How to catch bugs of the form sizeof(#define)

I'm sure there are sometimes good reasons for taking the sizeof() a #define in C, but I occasionally come across bugs where someone has taken the sizeof() a #define instead of the sizeof() a structure (and in my codebase I don't need to take the sizeof() a #define).
For example (contrived, but hopefully illustrates the point):
typedef struct my_struct
{
fields
} MY_STRUCT;
#define MY_DEFINE 1234
my_size = sizeof(MY_DEFINE); // Should be sizeof(MY_STRUCT)
Is there any easy, automated way to catch this?
Thanks for any help.
NickB
Well, no. Macros are macros. If the result of macro substitution is a valid expression (or type), then the code will compile. The compiler does not know what you want to do.
One thing that might help you (or not), is that in this specific example you want to sizeof a type as opposed to sizeof of an expression. If your coding standard insisted on always doing it through struct tag, as in
sizeof(struct my_struct)
then accidental mistakes like the specific one in your example would be less likely. Although other mistakes would not be.
You could probably replace your size of with a macro that somehow requires a type (and use it everywhere in place of ordinary sizeof). For example something like this
#define SIZE_OF_TYPE(T) ((T *) 0, sizeof(T))
would fail to compile with non-type argument. But it also will fail to compile with some type arguments.
Actually I don't know your context, but in general the whole idea seems counterproductive. A good programming practice is actually to avoid applying sizeof to types, preferring to apply it to expressions instead, as in
int *p = malloc(n * sizeof *p); /* good */
instead of
int *p = malloc(n * sizeof(int)); /* bad */
And you seem to want to move in the opposite direction.
Why are you using ALL CAPS in your typedef'd name? A typedef is a C language construct, as opposed to a C preprocessor construct. It's an identifier, just like any other identifier.
If you only use all caps for MACROs, it will be pretty obvious when you're using them.

Resources