First class member
I know the following is bad, but I was under the impression that the first member of the class is the starting address of the class. It is not right?
class A{
public:
int a;
int b;
};
class B{
public :
int x;
};
int main()
{
B *pb=new B();
A *pa=(A*)pb;
pa->a++;
}
I was under the impression that pb-> x will increment by 1. Is it always or undefined? Why does this change when we have user-defined constructors or virtual functions?
source to share
This only applies to true if your class is of type standard_layout. This can be verified using a trait like is_standard_layout
std::cout << std::is_standard_layout<A>::value << '\n';
std::cout << std::is_standard_layout<B>::value << '\n';
For other classes, you have additional information stored in memory that is compiler specific and not standardized. You can have a look at This question where some memory layouts are discussed and displayed.
For your second example / question, the standard has the following quote (5.2.10 / 7, draft N3337):
An object pointer can be explicitly converted to an object pointer of another type. When a prvalue v of type "pointer to T1" is converted to type "pointer to cv T2", the result is static_cast (static_cast (v)) if both T1 and T2 are standard layout types (3.9) and T2 alignment requirements are not stricter than T1 requirements, or if any type is invalid. Converting a prvalue of pointer-to-T1 to pointer-to-T2 (where T1 and T2 are object types and where T2's alignment requirements are no stricter than T1) and back to the original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
If I have read and interpreted this correctly, then your example is not listed as the alignment requirements for A are greater than the requirements for B. However, another way should be okay, for example:
int main()
{
A *pa=new A();
B *pb=reinterpret_cast<B*>(pa);
pb->x++;
std::cout << pa->a;
}
source to share
Yes, you are absolutely wrong, you can never take something like this for granted, these are compiler-specific contracts that C ++ does not guarantee.
I believe you are confused about classes with C ++ arrays: for example, a pointer to the first element of a char array is the same as a pointer to that array.
source to share