I have a code duplication situation where I have exact same body of struct but with different names. The body of struct is not small, hence there is risk of injecting error while modifying code in future. Following is just example to illustrate the problem:
struct read_data_on_disk {
int a;
char b;
};
struct read_data {
int a;
char b;
};
It is possible to define one of them, say read_data_on_disk and another be just defined as alias of it? I am looking for something like below:
typedef struct read_data_on_disk struct read_data; // this is wrong though
That's almost right. Try this:
struct read_data_on_disk {
int a;
char b;
};
typedef struct read_data_on_disk read_data;
But as dbush pointed out above, why have two structs if their content is identical?
I have a C program where I have two structures
struct one{
int a;
int b;
char *s;
int c;
};
struct two{
int a;
int e;
char *s;
int d;
};
Is possible to write a function that copies the values of the variables with the same type and name from struct one to struct two?
For example, in this case the function should do this
two.a = one.a;
two.s = one.s;
There's no way to automatically grab fields of a given name from a struct. While you could do something like this in Java with reflection, it can't be done in C. You just need to manually copy the relevant members.
You may write function macro like this:
#define CAT(A, B) A ## B
#define ARGS_ASSIGN(N, L, R, ...) CAT(_ARGS_ASSIGN, N) (L, R, __VA_ARGS__)
#define _ARGS_ASSIGN1(L, R, M0) L.M0 = R.M0;
#define _ARGS_ASSIGN2(L, R, M0, M1) L.M0 = R.M0; L.M1 = R.M1;
/* ... define sufficiently more */
and use in such way:
ARGS_ASSIGN(2, two, one, a, s)
In theory you could do this with a simple block copy function for your example above using the code below if you are certain that your compiler sequences the structure as sequenced in its type definition. However, I don't think it's a great idea. Block copy would be safer with two data structures of the same type as defined in one of the answers proposed above.
Example using block copy function:
void main(void)
{
struct one{
int a;
int b;
char *s;
int c;
};
struct two{
int a;
int e;
char *s;
int d;
};
// Place code that assigns variable one here
memcpy(&two, &one, sizeof(one));
}
Is there a way to design a macro that could ensure an element is at the start of a struct during it's definition? For example:
typedef struct {
START(int a);
} b;
// Becomes
typedef struct {
int a;
} b;
But generate a compiletime error when it isn't the first element?
typedef struct {
int c;
START(int a);
} b;
// Generate an error
I was thinking you could use a combo of the OFFSETOF and BUILD_BUG_ON_ZERO macros but this would require knowing the struct layout while initializing it, and produces an error because the variable is undeclared.
Is this possible in C?
Use a compile time assertion at the locations you actually assume that layout, instead of at the definition site. Of course you will need to actually define it at the start in order to pass the assertion.
Perhaps something like this would work for you:
#define typedef_header(x) typedef struct { x
typedef_header(int a);
int c;
} b;
int main()
{
b x;
}
I've got some code written in C with some fairly substantial structs used to hold data. I wanted to use tpl for serialization/deserialization of struct data for saving and loading the program's data instead of having to write a bunch of code to do it.
My problem is with the tpl_map() function: I can't seem to get it to parse a statement in which it would serialize an array of structs containing a struct containing an array of strings.
tpl's documentation doesn't necessarily say you can do this or that you can't do this. The thing I'd like to serialize would be described by A(S(i$(A(s)A(s)A(s)A(s)iiiiis)sssuussi)), but tpl_map() throws a parse error every time.
These are the relevant struct definitions:
typedef struct y {
char** a;
char** b;
char** c;
char** d;
int e;
int f;
int g;
int h;
int i;
char* j;
} y_t;
typedef struct x {
int a;
y_t y;
char* b;
char* c;
char* d;
unsigned int e;
unsigned int f;
char g[40];
char* h;
unsigned int i;
} x_t;
I'm attempting to serialize an array of x_t.
Chopping down the tpl format string to the minimal possible and working up, I find that it doesn't seem to like having an array inside an inner struct inside an outer struct. More specifically, the problem occurs with the A(i) in A(S($(A(i)))), for instance.
Any thoughts?
I have a question in initializing my structure array inside a structure array. for example if I have a code as below:
#include <stdio.h>
int main() {
typedef struct {
int a;
int b;
int c;
} FIRST_T;
typedef struct {
int x;
int y;
int z;
FIRST_T *p;
} SECOND_T;
FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}};
FIRST_T p2[]={{4,5,6},{7,8,9}};
SECOND_T my_second[]=
{
{1,2,3,p1},
{4,5,6,p2}
};
}
if I have to initialize my first array in second array intialization part itself, then how would I write my typedef of SECOND_T?
like
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
then how should be my SECOND_T?
I am sure I can't define it as:
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
Please help.
You can't define a type with unbounded array in C, you have to specify the dimension. So you either do:
typedef strut {
int x;
int y;
int z;
FIRST_T f[SOME_VALUE];
} SECOND_T;
and then initialize SOME_VALUE count of members always, or do it the way you did.
I don't think you can do this, i.e, initialize the FIRST_T inside the initialization of SECOND_T, other than the first way you do it. Think about it, how can the compiler tell how many FIRST_T are there in SECOND_T? The problem here is, you can NOT define an array of flexible size struct statically.
you can't to do like that:
SECOND_T my_second[]=
{
{1,2,3,{{1,2,3},{4,5,6},{7,8,9}}},
{4,5,6,{{1,1,1},{2,2,2}}}
};
with
typedef struct {
int x;
int y;
int z;
FIRST_T p[]; //(I know its a blunder)
} SECOND_T;
becase the compiler don't know how to malloc memory for this struct. if you must do like this, you should define
typedef struct { int x,y,z; FIRST_T p[CONST_VALUE];}SECOND_T;
but I advise you use the first style that you write.
I don't know if I completely capture the question that you have. If it is that you want to avoid to have to declare an auxiliary variable for the pointers in the structure you can use a compound literal as follows:
SECOND_T my_second[] = {
{1,2,3, &(FIRST_T){{1,2,3},{3,4,5},{6,7,8}}},
{4,5,6, &(FIRST_T){{4,5,6},{7,8,9}}}
};
You'd have a compiler that complies to C99 for that.