I had this struct the other day:
struct foo_t {
char a, b, c;
} *foo = (foo_t*)untyped_memory;
…but having a named type for it was excessive. However, its unnamed form:
struct {
char a, b, c;
} *bar = untyped_memory;
...did not compile because of pointer types being incompatible.
Is there any way to make it work?
If you have access to C++11 or above then you can use decltype i.e.
struct {
char a, b, c;
} *bar = (decltype(bar))untyped_memory;
Related
When declaring a pointer to a struct, both the following code snippets compile without error:
A)
struct Foo
{
int data;
Foo* temp; // line in question
}
B)
struct Foo
{
int data;
struct Foo* temp; //line in question
}
What is the significance to repeating the word "struct" in the declaration of the struct pointer (as in (B))? Are there any differences compared to not doing so (as in (A))?
Thank you for your consideration.
In C, struct keyword must be used for declaring structure variables, but it is optional in C++.
For example, consider the following examples:
struct Foo
{
int data;
Foo* temp; // Error in C, struct must be there. Works in C++
};
int main()
{
Foo a; // Error in C, struct must be there. Works in C++
return 0;
}
Example 2
struct Foo
{
int data;
struct Foo* temp; // Works in both C and C++
};
int main()
{
struct Foo a; // Works in both C and C++
return 0;
}
In the above examples, temp is a data member that is a pointer to non-const Foo.
I have a Union containing various struct member.
union U {
struct S1 as_s1;
struct S2 as_s2;
…
};
How can I cast pointer to struct as_s1 to a pointer to union U in C++?
I know because of this that it can be easily done using C casting. But I want to use the feature of Advance class type casting of C++ without causing any errors.
From the standard 6.9.2.4.
Two objects a and b are pointer-interconvertible if:
they are the same object, or
one is a standard-layout union object and the other is a non-static data member of that object (12.3),
one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object (12.2), or
there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (8.2.10).
This means that you can convert them to each other using reinterpret_cast. However, you cannot access the memory of wrong type. E.g., following is a well-defined code:
#include <iostream>
struct S1 {
int i;
};
struct S2 {
short int i;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
void printUnion(U* u, int type) {
if (type == 0){
S1 *s1 = reinterpret_cast<S1*>(u);
std::cout << s1->i << std::endl;
} else {
S2 *s2 = reinterpret_cast<S2*>(u);
std::cout << s2->i << std::endl;
}
}
int main() {
S1 s1{1};
printData(reinterpret_cast<U*>(&s1), 0);
S2 s2{2};
printData(reinterpret_cast<U*>(&s2), 1);
}
But, if you give a wrong type parameter to the printData-function, the behavior is undefined.
In c++ it is hard to imagine a program with a good design where the cast would be needed. In c if you already have a need for a union object there might be a case where this could be used to implement polymorphism (of course no reinterpret_cast there). Though it is usually done with void*.
The proper casting for such pointer casts is reinterpret_cast:
#include <stdio.h>
struct S1 {
int x,y;
};
struct S2 {
double a,b;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
int main() {
struct S1 mys1;
union U *uptr = reinterpret_cast<union U*>(&mys1);
uptr->as_s1.x = 42;
printf("%d\n",mys1.x);
return 0;
}
Beware that since sizeof(struct S1) < sizeof(struct S2), in this example, and you only allocated enough memory for the size of S1, if you try to do anything on uptr->as_s1.b you will corrupt the stack.
I have this code
template <class N>
inline N swap(N a, N b) {
int c = *a;
*a = *b;
*b = c;
}
with this function I get this error: error: 'N' does not name a type
Error compiling.
This is my normal function.
inline void swap(int *a, int *b) {
int c = *a;
*a = *b;
*b = c;
}
My problem is that I need to use this function with unsigned and normal ints.
Is it possible to do this with templates.
I think you want something like this:
template<typename T>
inline void swap(T* a, T* b) // Use T* if you're expecting pointers
^^^^ // Notice the return type
{
T c = *a;
*a = *b;
*b = c;
}
Change declaration of the pointer from int c to N* c because it may take another data type as parameter , in addition to that you can't put a value of a pointer in a normal variable .
Consider the sample code below:
class A
{
public:
A() : n(0) {}
int n;
};
class B
{
public:
B(A* a) : mA(a) { }
B(const A* a) : mConstA(a) { }
union {
A* mA;
const A* mConstA;
};
};
int main()
{
A a;
B b1(&a);
B b2(const_cast<const A*>(&a));
return 0;
}
At construction, b1 would have a mutable pointer to a, while b2 would have an immutable pointer to a. In this scenario, b1.mA equals b2.mConstA, and b1.mConstA equals b2.mA.
Are these equalities always true when you have a union of const and non-const object pointers?
Similarly, the code below compiles/runs fine:
int main()
{
const A a;
B b(&a);
b.mA->n = 3; // Blasphemy!!!
return 0;
}
But is it guaranteed for b.mA to always be equal to b.mConstA?
Are these equalities always true when you have a union of const and non-const members?
Yes, both pointers will refer to the same object in the same address. The bits in memory will be the same.
But is it guaranteed for b.mA to always be equal to b.mConstA?
Yes, their values will be the same, but that does not mean that you can really use it. This is equivalent to using const_cast, you will get a non-const pointer to the object, but if the object is really const, using that pointer to modify the object is undefined behavior.
Suppose I have following template class:
template<unsigned char I, unsigned char F>
class FOO
{
....
}
In the main function, I have many such variables, with different (I, F), like following,
int main()
{
.....
FOO<4, 2> a;
FOO<6, 3> b;
......
}
I want to retain the value of I or F for the defined variables in my main function. Of course, I can define a public/private members for FOO and save the value of (I, F) inside the FOO's constructor, like
template<I,F>
FOO<I,F>::FOO(){
i = I;
f = F;
}
Disadvantage of this method is obvious: It enlarge the size of the FOO. IMO, (I, F) of any variable can be determined at compiling time, so there should be a way to do this without creating local variable.
The usual way (like std::array in C++11) is to do the following:
constexpr unsigned char i() const { return I; }
constexpr unsigned char f() const { return F; }
If your compiler doesn't support constexpr, remove it.
Within your class definition, you can simply refer to the parameters literally (just like any other template parameters!).
But suppose you have this:
typedef Foo<10, 20> MyFoo;
MyFoo x; // what is I, what is K?
The customary thing is to reflect the template parameters inside the class definition:
template <int A, typename T> struct Foo
{
static int const a_value = A;
typedef T type;
// ...
};
Now you can say: MyFoo::type x; return MyFoo::a_value; etc. Note that integral static class constants don't usually need a definition unless you do something like take their address, so in most cases this won't have any cost in the compiled code -- the compiler simply substitutes the value whenever it sees the name of the constant.
you can simply use the template parameters, like this:
#include <iostream>
using namespace std;
template<unsigned char I, unsigned char F>
class FOO
{
public:
void bar() {
cout << "I is: "<<I<<endl;
}
char getI() {
return I;
}
};
using namespace std;
int main(){
FOO<4,2> a;
a.bar();
cout << "getI:"<<a.getI()<<endl;
}
you don't need a copy, as in your example (i = I)
BTW: fully capitalized names like FOO are usually by convention reserved for preprocessor Macros.