Storage size of 'i1' isn't known - c

it showing error in union item i1;
it says storage size of i1 isn't known
how to recover from this error
#include<stdio.h>
#include<string.h>
int main()
{
union item i1;
i1.x = 5;
printf("\n%d",i1.x);
i1.y = 3.5;
printf("\n%f",i1.y);
strcpy(i1.z,"C Programming");
printf("\n%s",i1.z);
return 0;
}
union item
{
int x;
float y;
char z[20];
};
please solve this problem

You should move the definition of item before declaring it in main(), otherwise the compiler will view it as an incomplete (undefined) type. This should work:
#include<stdio.h>
#include<string.h>
union item
{
int x;
float y;
char z[20];
};
int main()
{
union item i1;
i1.x = 5;
printf("\n%d",i1.x);
i1.y = 3.5;
printf("\n%f",i1.y);
strcpy(i1.z,"C Programming");
printf("\n%s",i1.z);
return 0;
}

Related

How to assign value to Struct properties in C

New to C, here is a simple Struct I have created.
typedef struct car {
float x, y;
unsigned char width, height;
} Cars;
My attempt to assign the x and y property of car:
Cars sedan;
sedan.x = 20;
sedan.y = 10;
Error
error: expected '=', ',', ';', 'asm' or 'attribute' before '.' token
Any ideas? Please help!
I'm guessing that you have the lines
Cars sedan;
sedan.x = 20;
sedan.y = 10;
outside a function. You cannot use
sedan.x = 20;
sedan.y = 10;
outside a function. Move those lines inside a function.
Another choice is to initialize the members of the struct using (Thanks #JonathanLeffler)
Car sedan = { .x = 20, .y = 10 };
Maybe you could try defining one member of struct in one line.
typedef struct car {
float x;
float y;
unsigned char width;
unsigned char height;
} Cars;
#include <stdio.h>
#include <string.h>
typedef struct car {
float x, y;
unsigned char width, height;
} Cars;
int main( ) {
Cars sedan;
sedan.x = 20;
sedan.y = 10;
printf( "value one : %f\n", sedan.x);
printf( "value two : %f\n", sedan.y);
}
Output :
value one : 20.000000
value two : 10.000000
You can also code structure as follow, :)
struct car {
float x, y;
unsigned char width, height;
};
int main( ) {
struct car sedan; /* Declare sedan of type car */
sedan.x = 20;
sedan.y = 10;
printf( "value one : %f\n", sedan.x);
printf( "value two : %f\n", sedan.y);
}

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));
}

Initializating struct error: 'theGrid' being used without being initialized

I am trying to create a 3d grid for my OpenCl/GL fluid. The problem Im having is that for some reason the my grid initialization function does not work properly. Here is my *.h, *.c setup and (at the end) call in main:
(grid.h):
#if RunGPU
#define make_float3(x,y,z) (float3)(x,y,z)
#define make_int3(i,j,k) (int3)(i,j,k)
#else
typedef struct i3{
int i,j,k;
} int3;
typedef struct f3{
float x,y,z;
} float3;
#define __global
#define make_float3(x,y,z) {x , y , z}
#define make_int3(x,y,z) {x , y ,z}
#endif
typedef struct grid3 * grid3_t; // u,v,w
typedef struct grid * grid_t; // p
struct grid3 {
__global float3* values_;
__global float * H_;
__global float * h_;
int dimx_;
int dimy_;
int dimz_;
} ;
struct grid {
__global float * values_;
int dimx_;
int dimy_;
int dimz_;
};
void grid3_init(grid3_t grid,__global float3* vel,__global float* H,__global float *h, int X, int Y, int Z);
(grid.c):
void grid3_init(grid3_t grid,__global float3* val,__global float* H,__global float *h, int X, int Y, int Z){
grid->values_ = val;
grid->H_ = H;
grid->h_ = h;
grid->dimx_ = X;
grid->dimy_ = Y;
grid->dimz_ = Z;
}
In main im initializing my grid like so:
int main(int argc, char** argv)
{
const int size3d = Bx*(By+2)*Bz;
const int size2d = Bx*Bz;
float3 * velocities = (float3*)malloc(size3d*sizeof(float3));
float * H = (float*)malloc(size2d*sizeof(float));
float * h = (float*)malloc(size2d*sizeof(float));
for(int i = 0; i < size3d; i++){
float3 tmp = make_float3(0.f,0.f,0.f);
velocities[i] = tmp;
if(i < size2d){
H[i] = 1;
h[i] = 2;
}
}
grid3_t theGrid;
grid3_init(theGrid, velocities, H, h, Bx, By, Bz); // <- ERROR OCCURS HERE
}
The error im getting is during runtime - "Run-Time Check Failure #3 - The variable 'theGrid' is being used without being initialized". But thats precisely the job of grid3_init?
As im trying to write code to work for both Host and GPU I have to sacrifice the use of classes and work strictly with structs - which I have less experience with.
At this point I dont really know what to google either, I appriciate any help i can get.
struct grid3 theGrid;
grid3_init(&theGrid, velocities, H, h, Bx, By, Bz);
You need to create grid3 instance and pass its pointer to grid3_init. Your existing code just uses uninitialized pointer.

C Typedef Struct / Union auto-cast

Im having a small math library for 3d vector and Im trying to "unify" it.
Instead of having multiple typedef struct for vector3f, vector3i, color3, angles etc... Im trying to put everything inside the same struct like this:
typedef struct
{
union
{
float x;
float r;
float ax;
int x_int;
};
union
{
float y;
float g;
float ay;
int y_int;
};
union
{
float z;
float b;
float az;
int z_int;
};
} vec3;
Everything works peachy as long as the type is float, however when it falls to int Im having some strange values (which is understandable). My question is: Is there a way to cast directly/automatically inside the structure definition or I have to create extra functions to typecast between float and int?
Due to the answers below, maybe I should modify my original question to the following:
What is the best way to "unify" (and by unify I mean have like 1 struct) to be able to handle at the same time the following:
vector3f (float x,y,z)
vector3i (int x,y,z)
RGB (float r,g,b)
RGB (unsigned char r,g,b)
euler angle (ax, ay, az)
Thanks in advance!
If you mean that you want to put '360.0f' into float z of a union and have int z_int == 3, or vice versa, you can't. That is not the purpose of a union, and the binary representation of 3 (an integer) and 3.0 (a floating point value) are dissimiliar.
However, you could just remove the int and cast one of the floats to an int.
#include <stdio.h>
#include <stdlib.h>
typedef struct genericStruct
{
void *valueOne;
void *valueTwo;
}GS;
int main()
{
GS *gs = malloc(sizeof(*gs));
int valueInt = 10;
float valueFloat = 3.141592653589;
int *inputIntPtr = (int*)malloc(sizeof(int));
float *inputFloatPtr = (float*)malloc(sizeof(float));
void *voidPtr = NULL;
*inputIntPtr = valueInt;
*inputFloatPtr = valueFloat;
voidPtr = inputIntPtr;
gs->valueOne = voidPtr;
int *outputIntPtr = (int*)malloc(sizeof(int));
outputIntPtr = gs->valueOne;
printf("Input ptr = %d\n", *inputIntPtr);
printf("Output ptr = %d\n", *outputIntPtr);
voidPtr = inputFloatPtr;
gs->valueTwo = voidPtr;
float *outputFloatPtr = (float*)malloc(sizeof(float));
outputFloatPtr = gs->valueTwo;
printf("Input ptr = %f\n", *inputFloatPtr);
printf("output ptr = %f\n", *outputFloatPtr);
free(gs);
free(inputIntPtr);
free(inputFloatPtr);
free(outputIntPtr);
free(outputFloatPtr);
return 0;
}
And this what I meant by using void types.
This is a small piece of code that i wrote for you.It should do the job.I hope i was able to do what you asked for...
typedef struct{
void *ptr1;
void *ptr2;
void *ptr3;
}VEC;
main(){
VEC v ;
VEC *ptr;
int a = 5;
double b = 6;
float c = 7;
v.ptr1 = NULL;
v.ptr2 = NULL;
v.ptr3 = NULL;
ptr = &v;
v.ptr1 = (int *)&a;
ptr->ptr1 = (int *)&a;
v.ptr2 = (double *)&b;
ptr->ptr2 = (double *)&b;
v.ptr3 = (float *)&c;
ptr->ptr3 = (float *)&c;
printf("%d\n",*(int *)v.ptr1);
printf("%d\n",*(int *)(ptr->ptr1));
printf("%lf\n",*(double *)v.ptr2);
printf("%lf\n",*(double *)(ptr->ptr2));
printf("%f\n",*(float *)v.ptr3);
printf("%f\n",*(float *)(ptr->ptr3));
}
Or change all variables to void pointer type and then cast them to float or integer. Is it OK?

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