Dereferencing pointers to members of union - c++

The following code prints '2' four times. Why does it never print '1'? Can someone explain me exactly what is happening here?
#include <iostream>
int main () {
union IntegersUnion {
int a;
int b;
};
IntegersUnion q;
q.a = 1;
q.b = 2;
std::cout << "(*(&q.a)) = " << (*(&q.a)) << std::endl;
std::cout << "(*(&q.b)) = " << (*(&q.b)) << std::endl;
std::cout << "(*(&(q.a))) = " << (*(&(q.a))) << std::endl;
std::cout << "(*(&(q.b))) = " << (*(&(q.b))) << std::endl;
return 0;
}

A union shares the memory between its members. By doing:
q.a = 1;
q.b = 2;
the second assignment overwrites the a.

union uses the same memory for all of its members.
So, when you assign q.b = 2;, q.a will be 2, too.

Every item in the union refers to the same location.
The most common use of union is something like this:
struct {
int dataTypeID;
union {
char char_here;
int number_here;
}
} incoming_data;
In this example, incoming_data is data imported from a file, where dataTypeID tells you what kind of data it is. (There are many file formats which optimize space in this fashion.)

Related

nlopt: Passed data structure gives me damaged values

I need to pass structure to the function Constraint::AddFixedOrientationAxis, however when I check the passed data their values are completely wrong. I have tried to use different datatypes but without any luck.
typedef struct{
size_t idx;
size_t axis_idx;
double axis_vector_1;
double axis_vector_2;
double axis_vector_3;
}AddFixedOrientationAxisData;
double Constraint::AddFixedOrientationAxis(const std::vector<double> &x, std::vector<double> &grad, void *data)
{
Eigen::VectorXd fixed_rot(3);
AddFixedOrientationAxisData *d = reinterpret_cast<AddFixedOrientationAxisData*>(data);
auto idx = d->idx;
auto axis_idx = d->axis_idx; // 0->x, 1->y, 2->z
fixed_rot << d->axis_vector_1, d->axis_vector_2, d->axis_vector_3;
std::cout << "idx: " << idx << std::endl;
std::cout << "axis: " << axis_idx << std::endl;
std::cout << "fixed_rot: " << fixed_rot << std::endl;
}
In the main, I call use it the same way as the tutorial is:
AddFixedOrientationAxisData fixed_orient_constraint_data;
fixed_orient_constraint_data.idx = 0;
fixed_orient_constraint_data.axis_idx = 0;
fixed_orient_constraint_data.axis_vector_1 = FK_q(0,0);
fixed_orient_constraint_data.axis_vector_2 = FK_q(1,0);
fixed_orient_constraint_data.axis_vector_3 = FK_q(2,0);
opt.add_equality_constraint(Constraint::AddFixedOrientationAxis, &fixed_orient_constraint_data);
The terminal output is:
idx: 93901286131024
axis: 93901286131080
fixed_rot:
4.63934e-310
-0.54938 //interestingly, this is the correct value
0.00838157 //interestingly, this is the correct value
As #{Some programmer dude} told me in the comments, the problem was that the variable was not alive when the function was called.

Alternatives to std::array for objects of different types in C++11

I am looking for better solutions on how to organize and access my data.
My data is a set of structures (_array_10 and _array_20 in the example below) that contain std::array of different sizes (see my_data below).
Ideally, I would like to access it as it was an array of structs with different lengths, but this is not allowed, since different lengths are different types.
The solution I have below works, but I find it extremely ugly (specially the array of void *).
Q1. Any ideas on how to have a safer, more efficient/portable, or at least less ugly solution?
Q2. Is the proposed solution without templates portable? It relies on the fact that the length is stored before the rest of the data, since casting the pointer to an object with wrong length would mess the access to all fields that come after the first field of variable length.
My limitations include:
C++11
standard libraries
no std::vector
memory usage prevents me from being able to simply allocate an array of my_data with the maximum possible length
the bulk of the data (_array_10, _array_20, etc) will be placed in a memory area reserved specially for it
Using data_view and template require knowledge of the length of the arrays in build time. It would be great if we could avoid it.
Question edited to include the solution proposed by Guillaume Racicot
#include <iostream>
#include <array>
std::array<void *, 2> _ptrs;
template <int length>
struct my_data
{
int array_length;
std::array<int, length> something;
std::array<int, length> data;
my_data()
{
array_length = length;
}
};
struct my_data_view
{
int array_length;
const int * something;
const int * data;
template <int length>
my_data_view(my_data<length> const & data_in) :
array_length(length),
something(data_in.something.data()),
data(data_in.data.data())
{}
};
template <int length>
void
print_element(int array_idx, int element)
{
my_data<length> * ptr = reinterpret_cast<my_data<length> *>(_ptrs[array_idx]);
std::cout << "array " << length << ", data[" << element << "] = " << ptr->data[element] << ".\n";
}
void
print_element(int array_idx, int element)
{
my_data<1> * ptr = reinterpret_cast<my_data<1> *>(_ptrs[array_idx]);
int length = ptr->array_length;
int data_to_print = 0;
switch (length)
{
case 10:
{
data_to_print = reinterpret_cast<my_data<10> *>(_ptrs[array_idx])->data[element];
break;
}
case 20:
{
data_to_print = reinterpret_cast<my_data<20> *>(_ptrs[array_idx])->data[element];
break;
}
}
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
void
print_element(my_data_view view, int element)
{
int length = view.array_length;
int data_to_print = view.data[element];
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
int
main()
{
my_data<10> _array_10;
my_data<20> _array_20;
_ptrs[0] = static_cast<void *>(&_array_10);
_ptrs[1] = static_cast<void *>(&_array_20);
_array_10.data[5] = 11;
_array_20.data[5] = 22;
std::cout << "using template\n";
print_element<10>(0, 5);
print_element<20>(1, 5);
std::cout << "\nwithout template\n";
print_element(0, 5);
print_element(1, 5);
std::cout << "\nusing data_view\n";
print_element(my_data_view(_array_10), 5);
print_element(my_data_view(_array_20), 5);
}
You could create a dynamic view class that don't allocate:
struct my_data_view
{
int array_length;
std::span<int> something;
std::span<int> data;
template<int length>
my_data_view(my_data<length> const& data) :
array_length{length}, something{data.something}, data{data.data}
{}
};
Spans simply are a pointer and a size. If you don't have access to std::span (which is from C++20) you can simply replace those member with int* and use array_length for the size.
This my_data_view type is used like that:
void
print_element(my_data_view view, int element)
{
int length = view.array_length;
int data_to_print = view.data[element];
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
This is the code that will work both with std::span and simple int*.

c++. possible to do this without getting error: 'was not declared in this scope'

c++. Is it possible to do this?
if (x>3)
int foo=10
else
long foo=10
without getting error:
was not declared in this scope
Yes you can, using std::variantC++17 or boost::variant.
std::variant<int, long> foo;
if(x > 3)
foo = 10;
else
foo = long(10);
And then access foo like so:
if(auto value = std::get_if<int>(&foo))
std::cout << "foo is int: " << *value << '\n';
else {
long value = std::get<long>(foo);
std::cout << "foo is long: " << value << '\n';
}
I don't know why you would want to do that though. A long is guaranteed to be able to hold all int values so you can just make foo of type long, and avoid std::variant altogether.
no you cannot because that variable x is scoped inside the if block so you cannot see it from outside:
int main()
{
if(!x)
int value = 100;
else
double value = 5.57;
cout << value << endl; // values is scoped to if statement or else's so it will be destructed
// this example is like what you have above
for(;;)
{
int a = 77;
if(a)
break;
}
cout << a << endl; // error a is undeclared identifier
return 0;
}

Printing a pointer-to-member-field

I was debugging some code involving pointers to member fields, and i decided to print them out to see their values. I had a function returning a pointer to member:
#include <stdio.h>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
I tried using cout:
#include <iostream>
int main()
{
std::cout << select(0) << " and " << select(3) << '\n';
}
I got 1 and 0. I thought the numbers indicated the position of the field inside the struct (that is, 1 is y and 0 is x), but no, the printed value is actually 1 for non-null pointer and 0 for null pointer. I guess this is a standard-compliant behavior (even though it's not helpful) - am i right? In addition, is it possible for a compliant c++ implementation to print always 0 for pointers-to-members? Or even an empty string?
And, finally, how can i print a pointer-to-member in a meaningful manner? I came up with two ugly ways:
printf("%d and %d\n", select(0), select(3)); // not 64-bit-compatible, i guess?
ptr_to_member temp1 = select(0); // have to declare temporary variables
ptr_to_member temp2 = select(3);
std::cout << *(int*)&temp1 << " and " << *(int*)&temp2 << '\n'; // UGLY!
Any better ways?
Pointers to members are not as simple as you may think. Their size changes from compiler to compiler and from class to class depending on whether the class has virtual methods or not and whether it has multiple inheritance or not. Assuming they are int sized is not the right way to go. What you can do is print them in hexadecimal:
void dumpByte(char i_byte)
{
std::cout << std::hex << static_cast<int>((i_byte & 0xf0) >> 4);
std::cout << std::hex << static_cast<int>(i_byte & 0x0f));
} // ()
template <typename T>
void dumpStuff(T* i_pStuff)
{
const char* pStuff = reinterpret_cast<const char*>(i_pStuff);
size_t size = sizeof(T);
while (size)
{
dumpByte(*pStuff);
++pStuff;
--size;
} // while
} // ()
However, I'm not sure how useful that information will be to you since you don't know what is the structure of the pointers and what each byte (or several bytes) mean.
Member pointers aren't ordinary pointers. The overloads you expect for << aren't in fact there.
If you don't mind some type punning, you can hack something up to print the actual values:
int main()
{
ptr_to_member a = select(0), b = select(1);
std::cout << *reinterpret_cast<uint32_t*>(&a) << " and "
<< *reinterpret_cast<uint32_t*>(&b) << " and "
<< sizeof(ptr_to_member) << '\n';
}
You can display the raw values of these pointer-to-members as follows:
#include <iostream>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
int main()
{
ptr_to_member x = select(0) ;
ptr_to_member y = select(1) ;
ptr_to_member z = select(2) ;
std::cout << *(void**)&x << ", " << *(void**)&y << ", " << *(void**)&z << std::endl ;
}
You get warnings about breaking strict anti-aliasing rules (see this link), but the result is what you might expect:
0, 0x4, 0x8
Nevertheless, the compiler is free to implement pointer-to-member functionality however it likes, so you can't rely on these values being meaningful.
I think you should use printf to solve this problen
#include <stdio.h>
struct test{int x,y,z;}
int main(int argc, char* argv[])
{
printf("&test::x=%p\n", &test::x);
printf("&test::y=%p\n", &test::y);
printf("&test::z=%p\n", &test::z);
return 0;
}

Deriving a pointer type to the non-pointer class member

In book named "Using C++" by Rob McGregor there is following example of using pointer-to-member operator
class mycls
{
public:
int member;
int *ptr;
};
void main()
{
mycls MyClass;
// Derive a pointer type to the non-pointer class member
int mycls::*member = &mycls::member;
MyClass.ptr = new int;
mycls* pMyClass = &MyClass;
pMyClass->*member = 5;
*MyClass.ptr = 10;
cout << "pMyClass->*member = " << pMyClass->*member << "\n"; // pMyClass->*member = 5
cout << "MyClass.*member = " << MyClass.*member << "\n"; // MyClass.*member = 5
cout << "*MyClass.ptr = " << *MyClass.ptr << "\n"; // *MyClass.ptr = 10
cout << "*pMyClass->ptr = " << *pMyClass->ptr << "\n"; // *pMyClass->ptr = 10
delete MyClass.ptr;
}
In this example I don't understand why member variable mycls::member becomes maybe a pointer after (guessing) this line of code:
int mycls::*member = &mycls::member;
What this does?
Suppose you had a local variable:
int member;
You could make a pointer to it with:
int *ptr = &member;
To get the pointer to member syntax, we just append mycls:: in the appropriate places:
int mycls::*member = &mycls::member;
It might be clearer with an example that shows how the pointer can switch between any members of the class that are of the correct type:
class C
{
public:
int a;
int b;
};
void main()
{
// make pointer to member, initially pointing to a
int C::*ptrToMember = &C::a;
C x;
C *ptrToObj = &x; // make pointer to object x
ptrToObj->*ptrToMember = 2; // store in a;
ptrToMember = &C::b; // change pointer to b
ptrToObj->*ptrToMember = 3; // store in b;
}
Note how we create the pointer to the member a before we've created an object of type C. It's only a pointer to a member, not a pointer to the member of a specific object. In the 'store' steps, we have to say which object as well as which member.
Update
In the comments the OP asked if this is the same:
int *ptr = &(ptrToObj->a);
No, it's not. That is a pointer to any int, anywhere in memory.
The easiest way to understand this is to think of what it means technically. A "pointer" is an absolute location in memory: where to find an object. A "pointer-to-member" is a relative location, sometimes called an offset: where to find an object within the storage of an outer object. Internally they are just numbers. A pointer-to-member has to be added to an ordinary pointer to make another pointer.
So if you have a pointer to an object (an int is an object!), you can use it to change what is stored at that absolute location in memory:
*ptr = 123;
But if you have a pointer-to-member, it is not a memory location. It is an offset, an amount to be added to a memory location. You cannot use it by itself. You must "add" it to an object pointer:
ptrToObj->*ptrToMember = 132;
This means: go to the location in memory ptrToObj, then move along by the distance ptrToMember.
He called the class member member and the pointer-to-member member, confusing the issue. Does renaming them like this help?
Class:
class SampleClass
{
public:
int m_data;
int* m_pointer;
};
Usage:
int main()
{
SampleClass sample;
// Derive a pointer type to the non-pointer class member
int SampleClass::*pointerToMember = &SampleClass::m_data;
sample.m_pointer = new int;
SampleClass* pSample = &sample;
pSample->*pointerToMember = 5;
*sample.m_pointer = 10;
// pSample->*pointerToMember = 5
cout << "pSample->*pointerToMember = "
<< pSample->*pointerToMember << "\n";
// sample.*pointerToMember = 5
cout << "sample.*pointerToMember = "
<< sample.*pointerToMember << "\n";
// *sample.m_pointer = 10
cout << "*sample.m_pointer = "
<< *sample.m_pointer << "\n";
// *pSample->m_pointer = 10
cout << "*pSample->m_pointer = "
<< *pSample->m_pointer << "\n";
delete sample.m_pointer;
}
[Code]
Edit: Re "I'm still currious whether int *ptr = &(ptrToObj->a); is the same as using pointer to a member like in the book":
It's not a pointer-to-member. It is just a normal pointer to memory that happens to be in an object.
You can see the syntax in use here:
Class:
class C
{
public:
int a;
int b;
};
Usage:
int main()
{
// make pointer to member, initially pointing to a
int C::*ptrToMember = &C::a;
C x = {10, 11};
C *ptrToObj = &x; // make pointer to object x
cout << "a initial value: " << ptrToObj->*ptrToMember << endl;
ptrToObj->*ptrToMember = 2; // store in a;
cout << "a after change: " << ptrToObj->*ptrToMember << endl;
ptrToMember = &C::b; // change pointer to b
cout << "b initial value: " << ptrToObj->*ptrToMember << endl;
ptrToObj->*ptrToMember = 3; // store in b;
cout << "b after change: " << ptrToObj->*ptrToMember << endl;
int* ptr = &(ptrToObj->a);
cout << "ptr to a: " << *ptr << endl;
ptr = &(ptrToObj->b);
cout << "ptr to b: " << *ptr << endl;
}
[Code]
The asterisk character in the declaration is part of the type.
Your declaration breaks down into
Type: int mycls::*
Variable name: member
Initialiser: = &mycls::member
This new variable member points is a member pointer to an int held in a mycls. It doesn't have to point to a mycls::member.