Casting one C structure into another - c

I have two identical (but differently named) C structures:
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
typedef struct {
double x;
double y;
double z;
} Vector3d;
Now I want to assign a CMAcceleration variable to a Vector3d variable (copying the whole struct). How can I do this?
I tried the following but get these compiler errors:
vector = acceleration; // "incompatible type"
vector = (Vector3d)acceleration; // "conversion to non-scalar type requested"
Of course I can resort to set all members individually:
vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;
but that seems rather inconvenient.
What's the best solution?

That's your only solution (apart from wrapping it into a function):
vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;
You could actually cast it, like this (using pointers)
Vector3d *vector = (Vector3d*) &acceleration;
but this is not in the specs and therefore the behaviour depends on the compiler, runtime and the big green space monster.

You could use a pointer to do the typecast;
vector = *((Vector3d *) &acceleration);

memcpy(&vector, &acceleration, sizeof(Vector3d));
Please note that this works only, if the physical layout of the structs in memory are identical. However, as #Oli pointed out, the compiler is not obliged to ensure this!

You use an utility function for that:
void AccelerationToVector( struct CMAcceleration* from, struct Vector3d* to )
{
to->x = from->x;
to->y = from->y;
to->z = from->z;
}

Why dont you use.
typedef CMAcceleration Vector3d;
(instead of creating a whole new structure)
in that case vector = acceleration; compiles just fine.

Another version of the utility function making use of C99:
static inline struct Vector3d AccelerationToVector(struct CMAcceleration In)
{
return (struct Vector3d){In.x, In.y, In.z};
}
With the compiler optimization turned up (e.g., -Os), this should turn into absolutely no object code when invoked.

This is achieved easily through a union:
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
typedef struct {
double x;
double y;
double z;
} Vector3d;
typedef union {
CMAcceleration acceleration;
Vector3d vector;
} view;
int main() {
view v = (view) (Vector3d) {1.0, 2.0, 3.0};
CMAcceleration accel = v.acceleration;
printf("proof: %g %g %g\n", accel.x, accel.y, accel.z);
}

A safe (albeit somewhat convoluted) way to do it would be to use a union:
union { CMAcceleration a, Vector3d v } tmp = { .a = acceleration };
vector = tmp.v;
Values are reinterpreted (since C99) when the accessed member is not the last set one. In this case, we set the acceleration and then we access the vector, so the acceleration is reinterpreted.
This is the way the NSRectToCGRect function is implemented, for example.

You could create a union with pointers that way you avoid copying data.
example :
struct Ocp1SyncHeader
{
aes70::OCP1::OcaUint8 syncVal;
aes70::OCP1::Ocp1Header header;
};
struct convertToOcp1SyncHeader
{
union
{
Ocp1SyncHeader* data;
const uint8_t* src;
};
convertToOcp1SyncHeader& operator=(const uint8_t* rvalue)
{
src = (const uint8_t*)rvalue;
return *this;
}
};
** access like this:
convertToOcp1SyncHeader RecvData;
RecvData = src; // src is your block of data that you want to access
** access members like this :
RecvData.data.header

Related

Initialize struct variable with previous one C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want to have a structure like below:
typedef struct Mystruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[] = {x_min, x_max, y_min, y_max};
};
My target is that the elements of the array params should be populated by { x_min, x_max, y_min, y_max}.
Is there anyway to achieve this structure in c?
In C you cannot do this, instead you could write a function which does the initialization for structure instance.
typedef struct Mystruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[4];
}Mystruct;
Mystruct GetMystruct( double p,
double x_min,
double x_max,
double y_min,
double y_max)
{
Mystruct my = { p, x_min,x_max,y_min,y_max, {x_min,x_max,y_min,y_max} } ;
return my;
}
Then, example :
Mystruct m = GetMystruct( 0.0, 42.1, 42.2, 42.3,42.4 );
If your intent is to have two different views of the same structure members, one by name and one by index, then this can be achieved in most C implementations with:
#include <stdio.h>
typedef struct foo
{
double p;
union
{
struct { double x_min, x_max, y_min, y_max; };
double params[4];
};
} foo;
int main(void)
{
foo x = { 1, 2, 3, 4, 5 };
for (size_t i = 0; i < 4; ++i)
printf("%g\n", x.params[i]);
}
There are some theoretical hazards to this (notably ensuring that the internal struct is not padded), but it will work in normal C implementations, and the hazards can be guarded against. (Checking that the size of the internal struct equals the size of the array will guard against padding. In order to check the size, you will need to give that struct a tag so it has a name.)
This uses a union to make the named members the same as the array elements (not just initialized to be the same, but to actually use the same member), and it uses anonymous struct and union to make the names of the members in the inner aggregates usable as names of members of the outer struct.
It would be possible to share the memory between the XY params and the entries in the array using an union:
typedef struct Mystruct
{
double p;
union {
struct {
double x_min;
double x_max;
double y_min;
double y_max;
};
double params[] = {x_min, x_max, y_min, y_max};
};
This would mean that the xy values would always be the same as the ones in the array
No you can't do that. You can't initialized member inside the declaration of structure. Because structure declaration defines a type not a variable. The way you showed it. Keeping a set of variables which are dependent among themselves. Even if you could why would you do that? Simply have an array.
typedef struct Mystruct
{
double p;
double params[4];
};
Now with this you can do the initialization part yourself. Or if you need both which is less likely you can keep both of them. By that I mean you can keep those 4 variables and keep an array and then while initializing you can explicitly set the content yourself. No way to wrap it like you did. Then you initialze like this
struct MyStruct mystruct = {
10.0,
{ 5, 6, 7, 8 }
};
Also if you want to keep two sets of variable being initialized with the same value you can follow the same method as shown above. But it is really meaningless given that it is nothing other two different variables having same values.
you can define a function inside the struct that initializes /sets the params array to the desired values, with the function containing a self-reference ( self ) to its containing structure. however the values in the params array and will only get 'synchronized' if this function is called ...
an example for this method is in "this" pointer in C (not C++) :
#include <stdio.h>
#include <stdlib.h>
typedef struct MyStruct
{
double p;
double x_min;
double x_max;
double y_min;
double y_max;
double params[4] ;
void (*setParams)();
}MyStruct;
void setParams(MyStruct* self) {
self->params[0]= self->x_min;
self->params[1]= self->x_max;
self->params[2]= self->y_min;
self->params[3]= self->y_max;
}
int main (int argc, char * argv[])
{
MyStruct myStruct = {1.24, 2.0, 4.0, 2.0, 4.0, {0,0,0,0}, NULL };
printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3] );
setParams(&myStruct);
printf("%f, %f, %f, %f \n", myStruct.params[0], myStruct.params[1], myStruct.params[2], myStruct.params[3] );
return 0;
}
however to 'synchronize' you have to call setParams()
Assuming you want 2 different copies of the same data, simply use common sense:
typedef struct
{
double x_min;
double x_max;
double y_min;
double y_max;
} xy_stuff;
typedef struct
{
double p;
xy_stuff xy;
xy_stuff params;
} Mystruct;
...
Mystruct ms =
{
.p = 1.0,
.xy = {1.0, 2.0, 3.0, 4.0},
.params = {1.0, 2.0, 3.0, 4.0},
};

How do I implement a struct with two floats in C?

error: must use "struct" tag to refer to type 'point'
All I want to do is store a coordinate as a struct.
This seems maddeningly simple to do but yet I cannot do it after visiting 20 websites and scouring Kernaghan's book.
What am I missing?
#include <stdio.h>
int main()
{
struct point
{
float x;
float y;
};
point.x = 0.0;
point.y = 1.9;
return 0;
}
You defined a type called struct point, not a variable name using that definition. You'd want to either define an instance of the struct using that type:
struct point mypoint; // In C, you could change mypoint to point, but that gets confusing
or (less common) declare variables with a type of the (possibly anonymous) struct definition by putting the name after the struct definition, before the semi-colon:
struct {
float x;
float y;
} point;
All you've declared is a type named struct point ; you haven't created an object named point to manipulate. You need a separate object definition, either by writing:
struct point {
float x;
float y;
};
struct point pvar;
or
struct point {
float x;
float y;
} pvar;
then you can manipulate the members of the object:
pvar.x = 0.0;
pvar.y = 1.9;
etc.
The "point" in your example is a struct tag, not a variable name. You have declared a type named struct point, but not any variable having that type. Where that declaration is in scope, you can declare variables having that type with the form
struct point my_point;
and then assign to their members as
my_point.x = 0.0;
my_point.y = 1.9;
What you have done, is similar to saying int = 3; This is more like it:
#include<stdio.h>
int main(void) {
struct point {
float x;
float y;
} s;
s.x = 0.0;
s.y = 1.9;
return 0;
}
But you should see compiler warnings, because the code assigns double values to float. It is better not to use the inferior float type unless you are forced to.
You need to have a structure object, ie instantiate the structure.
struct point obj;
obj.x = 0.0;
obj.y = 1.9;
Other options available are
struct point // Note,structure is tagged 'point' which enables multiple instantiations
{
float x;
float y;
}obj;
and
struct // Anonymous structure with one & only one instance possible
{
float x;
float y;
}obj;
and finally a typedef which is also a common practice
typedef struct point
{
float x;
float y;
}point;
point obj;
obj.x = 0.0;
obj.y = 1.9;

Returning multiple values in header file

I have a couple of questions all relating to the same code. In this code, I am trying to return the value for V, Ug1, Ug2, Vg1, and Vg2 from the "submerged_volume" function. Then, I want to use these values in the "centre_of_buoyancy" function. From that function, I want to return two values: Uc, and Vc. Finally, I want to call these functions using the header file in my main, and use the returned values from the functions for further calculations! I have not included the main body as it just has long calculations, so for the sake of space, here's a summarised version of my code:
#ifndef DATE_H_
#define DATE_H_
double submerged_volume(double L1, double L2, double Lavg, double H) {
//Boat parameters
double V1, V2;
double Ug1, Ug2, Vg1, Vg2; //lengths in U and V direction in relation to gravity
double V; //Submerged volume
//Initialising V, the value to calculate
V = 0;
//Volume Calculations
....
....
return V, Ug1, Ug2, Vg1, Vg2, V1, V2;
}
double centre_of_buoyancy(double Ug1, double Ug2, double Vg1, double Vg2, double V1, double V2);
//Calculations for Uc and Vc
.....
.....
return Uc, Vc;
}
#endif
I understand that this won't work as I can't return multiple variables. My question is, is there some way that I can do this? I'm very new to C and am not sure exactly how to use things like this!
You can define a struct holding those values, and return that from your function. (Check your C reference of choice for documentation of structs.)
BTW, you don't return anything "in a header", you only return something "from a function". And defining a function in a header file is asking for trouble. The idea is to declare the function in the header, and to define it in a source (.c) file.
Since I didn't really understand what you're trying to do, excuse me for using my own example.
Header:
#ifndef POINT_H_
#define POINT_H_
struct point_t
{
int x;
int y;
};
struct point_t move_horizontal( struct point_t point, int offset );
struct point_t move_vertical( struct point_t point, int offset );
#endif
Source:
#include "point.h"
struct point_t move_horizontal( struct point_t point, int offset )
{
point.x += offset;
return point;
}
struct point_t move_vertical( struct point_t point, int offset )
{
point.y += offset;
return point;
}
Main:
#include "point.h"
int main()
{
struct point_t some_point = { 0, 0 };
struct point_t other_point = move_horizontal( some_point, 42 );
return 0;
}
Non-sensical of course, but you might get the idea. Source and Main are two distinct compilation units, both of which include the header to know what they're talking about. The linker then puts them together, adds some runtime support, and generates your binary. (Your C book of choice should really have told you as much.)
There is a way to do this, and it's called struct. With struct, you aggregate data and look at them as a single type. That's very nice, since you can give a name to each part of the data:
struct boat_params
{
double submerged_volume;
double length_in_U1,
length_in_U2,
length_in_V1,
length_in_V2;
/* etc */
};
and then you fill this information and return it:
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H) {
//Boat parameters
struct boat_params params;
//Initialising V, the value to calculate
params.submerged_volume = 0;
//Volume Calculations (params.<fields>)
....
....
return params;
}
It makes sense to create a struct for the arguments of the function too, since they are many and they all look similar (all double). Creating a struct when you have many parameters helps the users of your function (and yourself) stay sane by easily assigning values to the parameters by their name, rather than some arbitrary order.
For example:
struct boat_data
{
double L1, L2; /* of course, give better names */
double Lavg;
double H;
};
struct boat_params submerged_volume(struct boat_data boat);
and the user would do:
struct boat_data boat;
struct boat_params params;
boat.L1 = ...;
boat.L2 = ...;
....
params = submerged_volume(boat); /* look how nice this looks */
Once you learn about pointers, you can make it more efficient by passing pointers rather than copying a bulk of data:
void submerged_volume(struct boat_data *boat, struct boat_param *params);
//Initialising V, the value to calculate
params->submerged_volume = 0;
//Volume Calculations (params-><fields>)
....
....
}
and later:
struct boat_data boat;
struct boat_params params;
boat.L1 = ...;
boat.L2 = ...;
....
submerged_volume(&boat, &params); /* less nice, but efficient and still short */
Typcially you would define the function prototype in the header file and the implementation in the .c file.
As #DevSolar said you could define a struct and return this from the function.
struct Boat
{
double V1, V2;
double Ug1, Ug2, Vg1, Vg2;
};
Alternatively you could pass in arguments by reference and modify the variable directly in memory through pointers.

C inheritance through type punning, without containment?

I'm in a position where I need to get some object oriented features working in C, in particular inheritance. Luckily there are some good references on stack overflow, notably this Semi-inheritance in C: How does this snippet work? and this Object-orientation in C. The the idea is to contain an instance of the base class within the derived class and typecast it, like so:
struct base {
int x;
int y;
};
struct derived {
struct base super;
int z;
};
struct derived d;
d.super.x = 1;
d.super.y = 2;
d.z = 3;
struct base b = (struct base *)&d;
This is great, but it becomes cumbersome with deep inheritance trees - I'll have chains of about 5-6 "classes" and I'd really rather not type derived.super.super.super.super.super.super all the time. What I was hoping was that I could typecast to a struct of the first n elements, like this:
struct base {
int x;
int y;
};
struct derived {
int x;
int y;
int z;
};
struct derived d;
d.x = 1;
d.y = 2;
d.z = 3;
struct base b = (struct base *)&d;
I've tested this on the C compiler that comes with Visual Studio 2012 and it works, but I have no idea if the C standard actually guarantees it. Is there anyone that might know for sure if this is ok? I don't want to write mountains of code only to discover it's broken at such a fundamental level.
What you describe here is a construct that was fully portable and would have been essentially guaranteed to work by the design of the language, except that the authors of the Standard didn't think it was necessary to explicitly mandate that compilers support things that should obviously work. C89 specified the Common Initial Sequence rule for unions, rather than pointers to structures, because given:
struct s1 {int x; int y; ... other stuff... };
struct s2 {int x; int y; ... other stuff... };
union u { struct s1 v1; struct s2 v2; };
code which received a struct s1* to an outside object that was either
a union u* or a malloc'ed object could legally cast it to a union u*
if it was aligned for that type, and it could legally cast the resulting
pointer to struct s2*, and the effect of using accessing either struct s1* or struct s2* would have to be the same as accessing the union via either the v1 or v2 member. Consequently, the only way for a compiler to make all of the indicated rules work would be to say that converting a pointer of one structure type into a pointer of another type and using that pointer to inspect members of the Common Initial Sequence would work.
Unfortunately, compiler writers have said that the CIS rule is only applicable in cases where the underlying object has a union type, notwithstanding the fact that such a thing represents a very rare usage case (compared with situations where the union type exists for the purpose of letting the compiler know that pointers to the structures should be treated interchangeably for purposes of inspecting the CIS), and further since it would be rare for code to receive a struct s1* or struct s2* that identifies an object within a union u, they think they should be allowed to ignore that possibility. Thus, even if the above declarations are visible, gcc will assume that a struct s1* will never be used to access members of the CIS from a struct s2*.
By using pointers you can always create references to base classes at any level in the hierarchy. And if you use some kind of description of the inheritance structure, you can generate both the "class definitions" and factory functions needed as a build step.
#include <stdio.h>
#include <stdlib.h>
struct foo_class {
int a;
int b;
};
struct bar_class {
struct foo_class foo;
struct foo_class* base;
int c;
int d;
};
struct gazonk_class {
struct bar_class bar;
struct bar_class* base;
struct foo_class* Foo;
int e;
int f;
};
struct gazonk_class* gazonk_factory() {
struct gazonk_class* new_instance = malloc(sizeof(struct gazonk_class));
new_instance->bar.base = &new_instance->bar.foo;
new_instance->base = &new_instance->bar;
new_instance->Foo = &new_instance->bar.foo;
return new_instance;
}
int main(int argc, char* argv[]) {
struct gazonk_class* object = gazonk_factory();
object->Foo->a = 1;
object->Foo->b = 2;
object->base->c = 3;
object->base->d = 4;
object->e = 5;
object->f = 6;
fprintf(stdout, "%d %d %d %d %d %d\n",
object->base->base->a,
object->base->base->b,
object->base->c,
object->base->d,
object->e,
object->f);
return 0;
}
In this example you can either use base pointers to work your way back or directly reference a base class.
The address of a struct is the address of its first element, guaranteed.

When are anonymous structs and unions useful in C11?

C11 adds, among other things, 'Anonymous Structs and Unions'.
I poked around but could not find a clear explanation of when anonymous structs and unions would be useful. I ask because I don't completely understand what they are. I get that they are structs or unions without the name afterwards, but I have always (had to?) treat that as an error so I can only conceive a use for named structs.
Anonymous union inside structures are very useful in practice. Consider that you want to implement a discriminated sum type (or tagged union), an aggregate with a boolean and either a float or a char* (i.e. a string), depending upon the boolean flag. With C11 you should be able to code
typedef struct {
bool is_float;
union {
float f;
char* s;
};
} mychoice_t;
double as_float(mychoice_t* ch)
{
if (ch->is_float) return ch->f;
else return atof(ch->s);
}
With C99, you'll have to name the union, and code ch->u.f and ch->u.s which is less readable and more verbose.
Another way to implement some tagged union type is to use casts. The Ocaml runtime gives a lot of examples.
The SBCL implementation of Common Lisp does use some union to implement tagged union types. And GNU make also uses them.
A typical and real world use of anonymous structs and unions are to provide an alternative view to data. For example when implementing a 3D point type:
typedef struct {
union{
struct{
double x;
double y;
double z;
};
double raw[3];
};
}vec3d_t;
vec3d_t v;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;
This is useful if you interface to code that expects a 3D vector as a pointer to three doubles. Instead of doing f(&v.x) which is ugly, you can do f(v.raw) which makes your intent clear.
struct bla {
struct { int a; int b; };
int c;
};
the type struct bla has a member of a C11 anonymous structure type.
struct { int a; int b; } has no tag and the object has no name: it is an anonymous structure type.
You can access the members of the anonymous structure this way:
struct bla myobject;
myobject.a = 1; // a is a member of the anonymous structure inside struct bla
myobject.b = 2; // same for b
myobject.c = 3; // c is a member of the structure struct bla
Another useful implementation is when you are dealing with rgba colors, since you might want access each color on its own or as a single int.
typedef struct {
union{
struct {uint8_t a, b, g, r;};
uint32_t val;
};
}Color;
Now you can access the individual rgba values or the entire value, with its highest byte being r. i.e:
int main(void)
{
Color x;
x.r = 0x11;
x.g = 0xAA;
x.b = 0xCC;
x.a = 0xFF;
printf("%X\n", x.val);
return 0;
}
Prints 11AACCFF
I'm not sure why C11 allows anonymous structures inside structures. But Linux uses it with a certain language extension:
/**
* struct blk_mq_ctx - State for a software queue facing the submitting CPUs
*/
struct blk_mq_ctx {
struct {
spinlock_t lock;
struct list_head rq_lists[HCTX_MAX_TYPES];
} ____cacheline_aligned_in_smp;
/* ... other fields without explicit alignment annotations ... */
} ____cacheline_aligned_in_smp;
I'm not sure if that example strictly necessary, except to make the intent clear.
EDIT: I found another similar pattern which is more clear-cut. The anonymous struct feature is used with this attribute:
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
I.e. a language extension / compiler plugin to randomize field order (ASLR-style exploit "hardening"):
struct kiocb {
struct file *ki_filp;
/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start
loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
void *private;
int ki_flags;
u16 ki_hint;
u16 ki_ioprio; /* See linux/ioprio.h */
unsigned int ki_cookie; /* for ->iopoll */
randomized_struct_fields_end
};
Well, if you declare variables from that struct only once in your code, why does it need a name?
struct {
int a;
struct {
int b;
int c;
} d;
} e,f;
And you can now write things like e.a,f.d.b,etc.
(I added the inner struct, because I think that this is one of the most usages of anonymous structs)

Resources