I did check the internet about it, but some uncertainty remains.
Casting one struct pointer to other - C
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
(What I read about libraries' binary compatibility was specific to C++)
There might be a solution to my problem but would require me to deeply modify my existing math & geometry library : Typesafe inheritance in C
Context
In C, the ability to cast a pointer to compatible types is handy, for example :
typedef struct s_pnt2
{
t_real x;
t_real y;
} t_pnt2;
typedef struct s_pnt3
{
t_real x;
t_real y;
t_real z;
} t_pnt3;
(Edited) Allows one to cast a 3D point into a 2D point (As R^2 is isomorphic to any hyperplane of R^3)
Furthermore :
typedef union u_vec2
{
t_pnt2 carthesian;
t_real matrix[2];
struct
{
t_real rep;
t_real imp;
} rectangular;
struct
{
t_real mod;
t_real arg;
} polar;
} t_vec2;
typedef union u_vec3
{
t_pnt3 carthesian;
t_real matrix[3];
struct
{
t_real rho;
t_real theta;
t_real phi;
} spherical;
struct
{
t_real r;
t_real theta;
t_real z;
} cylindrical;
} t_vec3;
Those unions allows one to explicitly express a point's coordinates in various systems, while the space used is no greater and most important, the compatibility remains.
While implementing functions converting a given vector from a system to another, I stumble upon the idea that storing the current system would be a good point. So I created an enum :
typedef enum e_type
{
CARTHESIAN,
CYLINDRICAL,
SPHERICAL,
POLAR = CYLINDRICAL,
RECTANGULAR = CARTHESIAN
} t_type;
Problem
I must now store a variable of type t_type (int), and face a problem : either I put it at the end, and loose compatibility between dimensions : Edit :
+---+ +---+
| x | matches | x |
+---+ +---+
| y | matches | y |
+---+ +---+
| t | doesn't | z |
+---+ +---+
| t |
+---+
or put it at the beginning (Just like X11 with XEvent), and loose compatibility with matrices, and (Edit) the ability to declare a vector like :
t_vec3 vector = (t_vec3){{x, y, z}}
Would there be a better way ?
Even if I don't require it in this instance, I would be interested if there's a way to keep the binary compatibility.
More generally, any advice on good habits are welcomed !
Thanks for your time
Edit : @llja : Yes I could do something like
typedef struct s_vec2t
{
t_type type;
t_vec2 p;
} t_vec2t
The downsides would be :
To access some data I should do something like :
t_vec2t point = (t_vec2t){CARTHESIAN, (t_vec2){{x, y}}} point.p.carthesian.x;
Meaning I must modify all my functions using points so that they now use typed points ?