How to inherit structure in a plain C - c

I am working in a plain C (embedded project, little memory) and I have a structure
typedef struct
{
int x;
int y;
int z;
float angle;
float angle1;
float angle2;
} Kind1;
There are cases when I need all fields, and there are cases when I need x, y and angle only.
In C++ I would create a base class with these 3 fields, would inherit from it another class with additional 3 fields and would instantiate one or another per need. How can I emulate this behaviour in plain C?
I know that I can make something like
typedef struct
{
int x;
int y;
float angle;
} Kind1;
typedef struct
{
Kind1 basedata;
int z;
float angle2;
float angle3;
} Kind2;
but then I cannot pass pointer to Kind2 where a pointer to Kind1 is requested.
I know that it is possible to typecast and offset the pointer, I just wonder if there is a better, safer way.

I know that it is possible to typecast and offset the pointer
Not necessarily:
void foo(Kind1*);
struct Kind2
{
Kind1 basedata;
int z;
float angle2;
float angle3;
}
//...
Kind2 k;
foo(&(k.basedata));

You can do it much like you would in C++:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int z;
float angle2;
float angle3;
}
struct Kind
{
Kind1 k1;
Kind2 k2;
}

It's not possible in plain C, the language has no such features. However, you could simplify the typecasts and offsets with pre-processor macros.

Examples below assume these definitions.
struct base { char c; } *a_base;
struct sub { struct base b; int i; } *a_sub;
Your "example" is in fact the (simplest) proper solution.
but then I cannot pass pointer to Kind2 where a pointer to Kind1 is requested.
Yes you can. The following is from the C11 standard but previous revisions had the same guarantees[citation needed].
n1570 6.7.1.1.15
... 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.
Therefore (struct base*)a_sub == &a_sub->b and ((struct base*)a_sub)->c == a_sub->b.c
So as long as your "super-struct" is the first member of your "sub-struct" you can treat one as the other when accessing by reference. Basically don't do this.
void copy(struct base *from, struct base *to)
{
*to = *from; // Oops, you just lost half your object.
}

In the case of limited memory, preserve sanity by declaring two different structs:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
int z;
float angle;
float angle2;
float angle3;
}
I once had to work code which used a union and preprocessor #defines to make the code look more readable. However, this quickly leads to madness. If the two structures are actually handled as a subclass, then rearranging the fields is the least evil:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
as long as they are carefully used with casting. If anything goes wrong though, there really ought to be debug version namechecking to prove it all is done correctly.
struct Kind1
{
char variant[6]; // initialized to "kind1"
int x;
int y;
float angle;
}
struct Kind2
{
char variant[6]; // initialized to "kind2"
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
function_expecting_kind2 (struct kind2 *p)
{
if (strcmp (p->variant, "kind2"))
error ("function expecting kind2 got '%s' instead", p->variant);
...
}

One way that I can think of which will save not more than 2*sizeof(float) bytes.
struct Kind2
{
int z;
float angle2;
float angle3;
}
struct Kind1
{
int x;
int y;
float angle;
struct Kind2 *k2;
}
here the whole saving will be based on how much memory the pointer eats.
Init the pointer only if it is needed.

Related

Function Pointer with void* return and void* parameters

I wrote a function pointer that has all void* so that it can be used for any numeric value
int
float
double.
But it is working only for the int addition function
For float and double addition functions, it throws compile time error.
Why is that so ?
If you uncomment the last two printf lines, you would receive error
#include<stdio.h>
int int_add(int x, int y) {
return x + y;
}
float float_add(float x, float y) {
return x + y;
}
double double_add(double x, double y) {
return x + y;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
printf("Sum= %d\n",(int*) do_operation(int_add, 1, 2));
/*printf("Sum= %f\n",(float*) do_operation(float_add, 1.20, 2.50));*/
/*printf("Sum= %lf\n",(double*) do_operation(double_add, 1.20, 2.50));*/
}
void * is a pointer type. You're not passing pointers, you're passing values, so that's not going to compile. It accidentally "works" for int because pointers themselves are represented as integers by most C compilers.
If you pass pointers to int, float, and double instead of the int, float, and double themselves, you will avoid that compiler error. You'd also need to change int_add and friends to take pointers, and you'd have to make sure you dereferenced the pointers before using them. You'll also have to return pointers, which means you'll have to malloc some memory on the heap, because the stack memory assigned to your local variables will be invalid once your function exits. You'll then have to free it all later... in the end, this is going to result in something considerably more complicated than the problem it appears you are trying to solve.
I have to ask why you are trying to do this? C is really not the best language for this type of pattern. I'd suggest just calling the int_add, float_add, etc. functions directly instead of trying to abstract them in this way.
So as per #charles-srstka suggestion I rewrote the code and then it worked as I wanted
#include<stdio.h>
#include<stdlib.h>
int* int_add(int *x, int *y) {
int *c = (int *)malloc(sizeof(int));
*c = *(int*)x + *(int*)y;
return c;
}
float* float_add(float *x, float *y) {
float *c = (float*)malloc(sizeof(float));
*c = *(float*)x + *(float*)y;
return c;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
int a = 1;
int b = 2;
int *c;
c = do_operation(int_add, &a, &b);
printf("%d\n",*c);
free(c);
float x = 1.1;
float y = 2.2;
float *z;
z = do_operation(float_add, &x, &y);
printf("%f\n",*z);
free(z);
}

How to pass pointers to vector extensions in C

I'm trying to use GCC's vector extensions, the exact code that I tried is:
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4* v, float x,float y,float z,float w){
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
int main(int argc, char* argv){
Vector4 a;
defVector(&a, 1, 2, 3, 4);
}
and keep getting errors:
incompatible types when assigning to type ‘Vector4 {aka __vector(4) float}’ from type ‘float’
v[0] = x;
Can't dereference it too or I get another error.
I would like to not copy the entire thing to the function stack every time I use it, and it's a necessity to make pointers to the return values like
int someFunc(Vector4 v, Vector4* r){
...
r[0] = return_value;
return 0;
}
I tried everything I know to access the values inside the funtion.
What I'm missing here?
Based on the OP's example in which a local function gets a "vector-extension" pointer:
#include <stdio.h>
#include <stdint.h>
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4 *v,float a, float b);
void defVector(Vector4 *v,float a, float b){
v[0] = *(Vector4*)&a;
v[1] = *(Vector4*)&b;
a = *(float*)&v[0] + 1.2;
b = *(float*)&v[1] + 2.1;
printf("%f,%f,%u",a,b,\
(uint32_t)sizeof(Vector4)/(uint32_t)sizeof(float));
}
int main(void) {
static Vector4 vectorA;
static float x1 = 3.4;
static float x2 = 4.3;
defVector(&vectorA,x1,x2);
}
This code will print (demo): 4.6,6.4,4 , so the value of two float were assigned to two units (being the number of units sizeof(Vector4)/sizeof(float)) of a Vector4 type variable.

C programming, doing multiple calculations in one function

Is it possible to create a function and do multiple calculations in that function, then create another function to print out the results of the calculations... I know a function can only return one value.
There are several ways to return multiple values. One way is to "package" them as a struct:
typedef struct
{
int x;
float y;
} Result;
Result add2( int x1, int x2, float y1, float y2)
{
Result r;
r.x = x1 + x2;
r.y = y1 + y2;
return r;
}
Another way to do it is to use parameters as your outputs:
void add2( int x1, int x2, float y1, float y2, int* x, float* y)
{
*x = x1 + x2;
*y = y1 + y2;
}
You could also do combinations of these.
One return value is for wimps! Simply define the function as
struct retval { int i; double d; size_t z; } func(void);
(replacing the contents of the struct and the parameters as applicable).
Be careful when doing this, though. In spite of what I said up top, in general there is no need for multiple returns.
You can create a struct with all the things ​​you are interested in, alloc it on heap, edit it inside a function, return the same struct that you have edited and at the end free the memory.
Alternatively, you can also pass the pointer and at the end free the memory.
Example:
typedef struct date_test {
int year;
int month;
int day;
} Date;
With this you create a structure that will contain 3 int values: year, month and day.
Alloc it on heap and check for errors:
Date *test = malloc(sizeof(Date));
if (test == NULL) {
perror("Malloc");
exit(EXIT_FAILURE);
}
Edit it inside a function and return the struct, example:
Date* test_f(Date* test)
{
test->year = 2017;
test->month = 05;
test->day = 29;
return test;
}
Then free the allocated memory:
free(test);

Casting data array to compatible struct

I'm in a situation where my code receives data from somewhere beyond my control in the form of a long list of floats.
These numbers get distributed to various functions
void myfunc(struct floatstruct* fs);
that take structs of the following form:
struct floatstruct
{
float a;
float b;
float c;
};
You get the idea.
I was wondering if there is a way to safely cast the array of floats to floatstruct to pass the data directly on to myfunc. I can add alignment attributes to floatstruct if necessary.
Example of desired behaviour:
struct mystruct1
{
float a;
float b;
float c;
};
struct mystruct2
{
float x;
float y;
};
extern void myfunc1(mystruct1*);
extern void myfunc2(mystruct2*);
void process_data(float* numbers)
{
myfunc1((struct mystruct1*)numbers);
myfunc2((struct mystruct2*)(numbers + 3));
}
The ideal solution is surely to change the system. But I'm looking for solutions within the given parameters.
Here's what I would do, given your peculiar requirements: ( I say this because 3 new floats here or there will make literally no noticeable difference unless you plan to use this on an arduino or phone or if you plan on having like tens of thousands...)
Anyways:
struct floatstruct
{
float (*a[3]);
};
{
int i;
struct floatstruct aStruct;
struct floatstruct bStruct;
float *num = numbers;
for (i = 0; i < 6; i++) {
if (i < 3)
aStruct.a[i] = num;
else
bStruct.a[i-3] = num;
num++;
}
myfunc1(&aStruct);
myfunc2(&bStruct);
}
Union could be what you need:
#pragma pack(sizeof(float))
struct mystruct1
{
float a;
float b;
float c;
};
struct mystruct2
{
float x;
float y;
};
#pragma pack()
typedef union
{
mystruct1 struct1;
mystruct2 struct2;
}structsUnion;
void myfunc1(structsUnion* values)
{
values->struct1.a; // to access members
}
void myfunc2(structsUnion* values)
{
values->struct2.x; // to access members
}
void process_data(float* numbers)
{
myfunc1((structsUnion*)(numbers));
myfunc2((structsUnion*)(numbers));
}

How do you make an array of structs in C?

I'm trying to make an array of structs where each struct represents a celestial body.
I don't have that much experience with structs, which is why I decided to try to use them instead of a whole bunch of arrays. However, I keep on running into numerous different errors. I've tried to implement the techniques that I've seen on various threads and on StackOverflow (such as Array of structs in C and C - initialize array of structs), however not all of them were applicable.
Further information for those who have read this far: I don't need any of this to be dynamic, I know/define the size of everything beforehand. I also need this to be a global array as I'm accessing this in several different methods which have defined arguments (i.e. GLUT methods).
This is how I'm defining the struct in my header:
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
I have a list of other global variables that I'm defining before I define the interior of the struct, and one of those is the array of this struct (basically, if I'm being too unclear in my fogged speak, the line below is above the stuff above):
struct body bodies[n];
Just so you know, n is something that I've legitimately defined (i.e. #define n 1).
I use this array in several different methods, but the easiest and least space consuming one is a simplified form of my main. Here I initialize all of the variables in each of the structs, just to set the variables for certain before I modify them in some way:
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
The current error that I'm facing is nbody.c:32:13: error: array type has incomplete element type where line 32 is where I'm making the array of the structs.
One last clarification, by header I mean the space above int main(void) but in the same *.c file.
#include<stdio.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
struct body bodies[n];
int main()
{
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
this works fine. your question was not very clear by the way, so match the layout of your source code with the above.
Another way of initializing an array of structs is to initialize the array members explicitly. This approach is useful and simple if there aren't too many struct and array members.
Use the typedef specifier to avoid re-using the struct statement everytime you declare a struct variable:
typedef struct
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}Body;
Then declare your array of structs. Initialization of each element goes along with the declaration:
Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};
To repeat, this is a rather simple and straightforward solution if you don't have too many array elements and large struct members and if you, as you stated, are not interested in a more dynamic approach. This approach can also be useful if the struct members are initialized with named enum-variables (and not just numbers like the example above) whereby it gives the code-reader a better overview of the purpose and function of a structure and its members in certain applications.
So to put it all together by using malloc():
int main(int argc, char** argv) {
typedef struct{
char* firstName;
char* lastName;
int day;
int month;
int year;
}STUDENT;
int numStudents=3;
int x;
STUDENT* students = malloc(numStudents * sizeof *students);
for (x = 0; x < numStudents; x++){
students[x].firstName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].firstName);
students[x].lastName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].lastName);
scanf("%d",&students[x].day);
scanf("%d",&students[x].month);
scanf("%d",&students[x].year);
}
for (x = 0; x < numStudents; x++)
printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);
return (EXIT_SUCCESS);
}
I think you could write it that way too. I am also a student so I understand your struggle. A bit late response but ok .
#include<stdio.h>
#define n 3
struct {
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}bodies[n];
move
struct body bodies[n];
to after
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
Rest all looks fine.
Solution using pointers:
#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double *mass;
};
int main()
{
struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
That error means that the compiler is not able to find the definition of the type of your struct before the declaration of the array of structs, since you're saying you have the definition of the struct in a header file and the error is in nbody.c then you should check if you're including correctly the header file.
Check your #include's and make sure the definition of the struct is done before declaring any variable of that type.
You can do it in a same manner as you create the array of numbers but wrap the element's values in braces like this ->
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
Here is full code
#include <stdio.h>
struct Wrestler
{
char firstName[20];
char secondName[20];
};
void pIntro(struct Wrestler *s)
{
printf("Hi, I am %s %s.\n", s->firstName, s->secondName);
};
int main(int argc, char const *argv[])
{
#define count 8
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
for (int i = 0; i < count; i++)
{
pIntro(&(studs[i]));
}
return 0;
}

Resources