Member variable aliasing in a simple struct using union - c++

I have a simple point struct that I would like to inherit:
struct PointXYZ
{
double x, y, z;
};
class extendedPoint : public PointXYZ
{
public:
double getXYZ(int i);
void setXYZ(int i, double value);
private:
int moreproperties;
};
The get-set function is indexed because I'd like to be able to loop through getting and setting the xyz values. I'd like to link the concept of indexed xyz and standalone x,y,z by modifying my base class as described in the answer to this post:
struct PointXYZ
{
union {
struct {
double x, y, z;
};
double xyz[3];
};
};
class extendedPoint : public PointXYZ
{
public:
double getXYZ(int i) { return xyz[i]; }
void setXYZ(int i, double value) { xyz[i] = value; }
private:
int moreproperties;
};
But this post directly contradicts the first post on whether the following is valid:
double dostuff()
{
PointXYZ p;
p.x = 123.88;
return p.xyz[0];
}
So, is PointXYZ's use of union valid c++ and consistent between compilers or not?

From the standard:
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time. [ Note: One special guarantee
is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout
structs that share a common initial sequence (9.2), and if an object of this standard-layout union type
contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2. — end note ]
Seems to me that the special guarantee indicates that
struct PointXYZ {
union {
struct {
double xyz[3];
};
struct {
double x, y, z;
};
};
};
should work just fine when reading the member that was not last written (See it happen).
Note, however, that according to the specs, your example of
struct PointXYZ {
union {
struct {
double xyz[3];
};
double x, y, z;
};
};
is undefined behaviour when reading the member that was not last written (See it happen). When setting xyz[0], xyz[1] and xyz[2], all of x, y and z have the same value as xyz[0] in the linked example. I would expect most compilers to behave like this, but the standard does not guarantee it.

struct PointXYZ {
union {
double xyz[3];
struct {
double x, y, z;
};
};
};
Depending on the compiler / platform, you may have data alignment issues (it's possible though unlikely).
x, y, z may not reside in memory in correspondence with xyz[0], xyz[1], xyz[2].
C++ guarantees that elements of the xyz array are laid out contiguously, but it only guarantees that the address of an element of the struct is greater than the address of all earlier-declared elements (of course many compilers offer #pragma to control packing and alignment).
About the type punning matter (the practice of reading from a different union member than the one most recently written to)...
you could say that this isn't type punning (types match, so there is no pun, it's merely aliasing), but still, from an the viewpoint of the language standard, the member written to and read from are different, which is undefined in C++.
Anyway, generally, you'll have the expected result...
With GCC it's even guaranteed to work (even with -fstrict-aliasing):
Type punning
A member of a union object is accessed using a member of a different type
As a side note consider that anonymous unions are permitted but C++ prohibits anonymous structs (a lot of compilers allow them).
What about the following solution?
class PointXYZ
{
public:
double getXYZ(unsigned i) { return xyz[i]; }
void setXYZ(unsigned i, double value) { xyz[i] = value; }
double &x() { return xyz[0]; }
double &y() { return xyz[1]; }
double &z() { return xyz[2]; }
private:
double xyz[3];
};

Related

How to cast one struct to another type with identical members?

If I'm given a struct variable like:
struct Quaternion {
float x;
float y;
float z;
float w;
}
But I need to call a function expecting a
struct Vector {
float x;
float y;
float z;
float w;
}
Is there a way in C++ to cast a variable of type Quaternion to type Vector?
You can write a converting constructor:
struct Quaternion {
float x;
float y;
float z;
float w;
explicit Quaternion(const Vector& vec) : x(vec.x),y(vec.y),z(vec.z),w(vec.w) {}
}
And similar for the other way.
In case you are looking for a way that does not require to copy the members, then I am not aware of a portable way to do that, and members having the same name does not help for that.
On the other hand, having same named members helps to write generic code like this:
template <typename T>
void foo(const T& t) {
std::cout << t.x << t.y << t.z << t.w;
}
You can call this with either a Quaternion or a Vector without needing to convert between them.
In case you cannot modify any existing code (not the structs nor the function you want to call), you can write a simple function to do the conversion (as suggested by ShadowRanger in a comment):
Vector Quat2Vect(const Quaternion& q) {
return {q.x,q.y,q.z,q.w};
}
If, as you said in a comment, you can't change to the two types, you could possibly "solve" the problem by using yet another type:
struct MyVector {
float x;
float y;
float z;
float w;
operator Quaternion() { return Quaternion{x, y, z, w}; }
operator Vector() { return Vector{x, y, z, w}; }
};
My advice: It's probably better to pick one or the other as the main type in your code and use a separate conversion function.
What I think you're hoping for, given that you specifically asked about "cast", is to use a cast to go from one to the other.
Vector v = {1, 2, 3, 4};
Quaternion* q = reinterpret_cast<Quaternion*>(&v);
do_something_with_quart(*q); // Could modify v if pass by reference
Strictly speaking, this is undefined behaviour, although it is overwhelmingly likely to work in practice, but I still wouldn't recommend it. If you're really desparate to do something cast like, it's legal to use memcpy so long as the member variables are the same type in the same order (and there are no virtual methods):
Vector v = {1, 2, 3, 4};
Quaternion q;
memcpy(&q, &v, sizeof(v));
do_something_with_quart(q);
memcpy(&v, &q, sizeof(v)); // Copy back any change
Although the language and documentation describes memcpy as a copying function, it has certain magical properties that often in practice make it identical to the previous block of code. But I would also strongly advise against this. I mean, yuck! Just look at it!!
This is just an addition to largest_prime_is_463035818's answer to point out that the members don't have to have the same name in order to write a generic function to use them. So long as there are an equal number of members, all are publicly accessible, and they have the same types, you can decompose objects with a structured-binding and use that.
template <typename T>
void foo(const T& t) {
auto const & [x, y, z, w] = t;
std::cout << x << y << z << w;
}

Delphi absolute in C++

Is there an equivalent to Delphi's absolute in C++? I want to do the following:
// Structure A
struct A
{
double X;
double Y;
double Z;
}
// Structure B
struct B : A
{
double U absolute X;
double V absolute Y;
double W absolute Z;
}
I can use double & U = X in structure B but this will generate an additional pointer and change the size of the structure. Union is - I think - also not a solution, because structure B inherits structure A.
What I really want is to have access to the same memory by accessing for example X or U.
I like the idea of user2079303's answers, but want to inverse it.
Note - the question is named wrong and is violating "what is your real goal" or "show me your Z" rule. We do not need to mimic absolute keyword - it is total nonsense! we want to make pseudonyms for the record properties and use them interchangeably.
What I really want is to have access to the same memory by accessing for example X or U.
The quoted line is the ONLY line in the question that talks about the problem essence - making full pseudonyms.
So, let's start where user2079303 stopped and use the fact that C's unions do not have to be named, like it was used in https://stackoverflow.com/a/13624921/976391
So we just inverse the scopes.
/*union*/ struct coordinates {
/*struct*/ union {
double X;
double U;
};
/*struct*/ union {
double Y;
double V;
};
/*struct*/ union {
double Z;
double W;
};
};
Short version: There is no equivalent of the described language feature.
Long version C++:
There isn't an equivalent in C++. The member reference that you suggest gives you the same syntax, but indeed increases the size of the object.
Another close alternative is a member function, that returns a reference. That has no overhead (assuming inline expansion). A function call has different syntax than referencing a member though. But perhaps having identical syntax with member access is not important so this is what I suggest.
Long version C:
There is no inheritance in C at all, so there is nothing like the described "absolute" in it either.
we have several kinds of coordinates. Some of them are named x, y, z others (in another system) are named u, v, w.
Given this context, I would suggest a union (EDIT: It's better to swap the union and struct relation, see https://stackoverflow.com/a/41148089/2079303):
union coordinates {
struct {
float x, y, z;
} xyz;
struct {
float u, v, w;
} uvw;
};
If you want to interchangeably use XYZ and UVW, you can let each convert to the other.
// forward declare
struct B;
struct A
{
double X;
double Y;
double Z;
operator B() const;
}
struct B
{
double U;
double V;
double W;
operator A() const;
}
A::operator B() const { B b; b.U = X; b.V = Y; b.W = Z; return b; }
B::operator A() const { A a; a.X = U; a.Y = V; a.Z = W; return a; }

C++ Is there a way how to simulate union behavior between child and parent classes?

is there a way how to simulate union behavior? See following code:
// this is ideal interface, which I would like to simulate
struct IdealInterface{
union{
struct{float r,g,b;};
struct{float x,y,z;};
};
};
// this is real parent object I should not change
struct Parent{
float r, g, b;
};
// this interface has ok behavior,
// but sizeof(Child0) != sizeof(Parent)
// which causes problems
struct Child0:public Parent{
float & x, & y, & z;
Child0() : Parent(), x(r), y(g), z(b){ };
};
// this has ok size, but interface is different
struct Child1:public Parent{
float & x(){ return r; }
float & y(){ return g; }
float & z(){ return b; }
};
So as described, I should keep Parent class, and I should derive my child class from Parent. I should not create different types and play with the type conversions. Thus, is it possible to create derived class (form Parent) with the same interface as IdealInterface class has?
If you mean identical behavior to a union then no, not without actually using a union.
You could always just hide the underlying data:
class Vertex
{
Vertex();
Vertex(float,float,float);
float& x() { return r;}
float& y() { return g;}
float& z() { return b;}
float& r() { return r;}
float& g() { return g;}
float& b() { return b;}
void r(float rComponent) { this->r = rComponent; }
...
private:
float r, g, b;
}
However, the downside to this approach is you must call the methods vs. accessing the underlying variable like you can do with the union.
If you want:
Vertex v;
v.x = 1.0f
Then you would want to use a union.
Answer:
Firstly, I have some words for commentators. I asked a pretty straight question. What I got? For example answers about sizeof properties, which were not posed (btw, yeah in this case I have guarantee about sizeof - this is c++, not a kind of today common wild language).
Why I cannot use IdealInterface. Problem is more complex. I want to edit bigger pack of code with introduced constraints and dependencies. Thus this is the question and I cannot redefine question, however it implies simpler solution.
Answer: NO, it is not possible.
Why? It is based on properties of anonymous structs and unions.
Nearest approach: For my purpose, nearest approach is to use memory model as parameter.
struct BASIC_MEMORY_MODEL{
float x, y, z;
BASIC_MEMORY_MODEL() :x(), y(), z(){}
};
struct ADVANCED_MEMORY_MODEL{
union{
struct { float x, y, z; };
struct { float r, g, b; };
};
ADVANCED_MEMORY_MODEL() :x(), y(), z(){}
};
template<typename MEMORY_MODEL = BASIC_MEMORY_MODEL>
struct ParentBase : public MEMORY_MODEL{};
typedef ParentBase<> Parent;
struct Child : public ParentBase < ADVANCED_MEMORY_MODEL > {};

C++: Custom data type - typecasting and union issues

What I'm trying to do is create a new custom data type that behaves like all other primitive types. Specifically, this data type appears like a Fixed Point fraction.
I've created a class to represent this data type, called "class FixedPoint", and in it there are ways to typecast from "FixedPoint" to "int" or "double" or "unsigned int", etc. That is fine.
Now, what if I want to cast from "int" to "FixedPoint"? Originally my solution was to have a constructor:
FixedPoint(int i) { /* some conversion from 'int' to 'FixedPoint' in here */ }
This works...but you cannot put it into a union like so:
union {
FixedPoint p;
};
This will break, because "FixedPoint" does not have an implicit trivial constructor (we just defined a constructor, "FixedPoint(int i)").
To summarize, the whole issue is "we want to cast from some type T to type FixedPoint without explicitly defining a constructor so we can use our type FixedPoint in a union".
What I think the solution is but cannot find any evidence online:
Define an overloaded global typecast operator to cast from "int" to "FixedPoint".
Is there a way to do this without using class constructors? I'd like to be able to use this class in a union. What I've tried (in global scope):
operator (FixedPoint f, int a) { ... } //compiler complains about this is not a method or non-static.
And a little example to show unions don't like constructors (they like POD)
class bob
{
public:
bob(int a) { m_num = a; }
private:
int m_num;
};
void duck()
{
union
{
bob a;
};
}
This error seen in Visual Studio is:
error C2620: member 'duck::<unnamed-tag>::a' of union 'duck::<unnamed-tag>' has user-defined constructor or non-trivial default constructor
Any ideas?
Thanks
I am having a hard time at seeing what you would try to use this for. It seems smelly to have to constantly ensure that sizeof(FixedPoint) == sizeof(int) and, assuming that, there are other hidden gotchas, like endianness. Maybe I should back up a little bit here, unions only "convert" a value from one type to another in that it takes a chunk of memory and references it as a different type. i.e.
union BadConverter
{
int integer;
double fraction;
};
BadConverter.fraction = 100.0/33.0;
BadConverter.integer = ?;
I am pretty sure integer is not going to be 3, it is going to whatever the memory chunk of the double is that the integer bytes share with it.
Unions don't seem to be a very good fit for this sort of thing. I would think just defining a bunch of assignment operators from all the primitive types. i.e.
class FixedPoint
{
FixedPoint& operator=(int value);
FixedPoint& operator=(double value);
..etc..
//Maybe something like this?
template<typename T>
FixedPoint& operator=(const T& value)
{
value = boost::lexical_cast<int>(value);
return *this;
}
}
Custom conversion operators must be a member of the class that is being converted from. A non-trivial constructor is not required.
EDIT: I reworked the example to utilize a union since this is what you were asking about.
EDIT2: See below if you are trying to go the other way (construction) and don't want constructors.
#include <string>
#include <sstream>
using namespace std;
class FixedPoint
{
public:
operator std::string() const
{
stringstream ss;
ss << x_ << ", " << y_;
return ss.str();
}
int x_, y_;
};
union Items
{
FixedPoint point_;
int val_;
};
int main()
{
Items i;
i.point_.x_ = 42;
i.point_.y_ = 84;
string s = i.point_;
}
If you're trying to go the other way -- eg, from an int to FixedPoint in my example -- then the normal way to do this is indeed to use a conversion constructor. Given that you don't want a non-trivial constructor, you have to resort to a conversion function.
FixedPoint make_fixed_point(int x, int y)
{
FixedPoint ret;
ret.x_ = x;
ret.y_ = y;
return ret;
}
union Items
{
FixedPoint point_;
int val_;
};
int main()
{
Items i;
i.point_ = make_fixed_point(111,222);
}
Can't you just add a default constructor that'll allow it to be part of the union.
For example:
class bob
{
public:
bob(int a=0) { m_num = a; }
private:
int m_num;
};
void duck()
{
union
{
bob a;
};
}
By giving the a=0 default, it should be able to be put in a union. I didn't try it myself, though.

C++ union array and vars?

There's no way to do something like this, in C++ is there?
union {
{
Scalar x, y;
}
Scalar v[2];
};
Where x == v[0] and y == v[1]?
Since you are using C++ and not C, and since they are of the same types, why not just make x a reference to v[0] and y a reference to v[1]
How about
union {
struct {
int x;
int y;
};
int v[2];
};
edit:
union a {
struct b { int first, second; } bee;
int v[2];
};
Ugly, but that's more accurate
Try this:
template<class T>
struct U1
{
U1();
T v[2];
T& x;
T& y;
};
template<class T>
U1<T>::U1()
:x(v[0])
,y(v[1])
{}
int main()
{
U1<int> data;
data.x = 1;
data.y = 2;
}
I've used something like this before. I'm not sure its 100% OK by the standard, but it seems to be OK with any compilers I've needed to use it on.
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
You can add bounds checking etc to operator[] if you want ( you probably should want) and you can provide a const version of operator[] too.
If you're concerned about padding (and don't want to add the appropriate platform specific bits to force the struct to be unpadded) then you can use:
struct Vec2
{
float x;
float y;
float& operator[](int i) {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
const float& operator[](int i) const {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
};
I was looking for a similair thing and eventually came up with a solution.
I was looking to have a data storage object that I could use as both an array of values and as individual values (for end-user flexibility in writing Arduino libraries).
Here is what I came up with:
class data{
float _array[3];
public:
float& X = _array[0];
float& Y = _array[1];
float& Z = _array[2];
float& operator[](int index){
if (index >= 3) return _array[0]; //Make this action whatever you want...
return _array[index];
}
float* operator&(){return _array;}
};
int main(){
data Test_Vector;
Test_Vector[0] = 1.23; Test_Vector[1] = 2.34; Test_Vector[2] = 3.45;
cout<<"Member X = "<<Test_Vector.X;
cout<<"Member Y = "<<Test_Vector.Y;
cout<<"Member Z = "<<Test_Vector.Z;
float* vector_array = &Test_Vector;
cout<<"Array = {"<<vector_array[0]<<", "<<vector_array[1]<<", "<<vector_array[2]<<"}";
}
Thanks to Operator overloading, we can use the data object as if was an array and we can use it for pass-by-reference in function calls (just like an array)!
If someone with More C++ experience has a better way of applying this end product, I would love to see it!
EDIT: Changed up the code to be more cross-platform friendly
Given your example:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
As others have noted, in general, the standard does not guarantee that there will be no padding between x and y, and actually compilers inserting padding in structures is pretty common behavior.
On the other hand, with solutions like:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
what I don't like mainly is the fact that I have to mention x, y twice. For cases where I have more than just a few elements (say 10), this becomes much less readable and harder to maintain - e.g. if you want to change the order of x,y then you have to change the indexes below too (well not mandatory but otherwise order in memory wouldn't match order of fields, which would not be recommended). Also, U can no longer be a POD since it needs a user-defined constructor. And finally, the x & y references consume additional memory.
Hence, the (acceptable for me) compromise I've come up with is:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
With this you can then do:
Point p;
for ( int i = 0; i < PtCoord::COUNT; i++ )
p.coords[i] = 100;
std::cout << p.coords[PtCoord::X] << " " << p.coords[PtCoord::Y] << std::endl;
// 100 100
A bit sophisticated but I prefer this over the references suggestion.
Depending on what "Scalar" is, yes, you can do that in C++. The syntax is almost exactly (maybe even exactly exactly, but I'm rusty on unions) what you wrote in your example. It's the same as C, except there are restrictions on the types that can be in the unions (IIRC they must have a default constructor). Here's the relevant Wikipedia article.
With C++11 you have anonymous unions and structs which just export their definitions to the enclosing scope, so you can do this:
typedef int Scalar;
struct Vector
{
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
};