I was studying object oriented C programming (how to implement virtual tables) and I saw some castings to do initialization that I would like to know if:
1 - Is there any undefined behaviors?
2 - Is this code portable?
3 - Is it also valid (well defined and portable) in C++?
In the actual code that I was studying, instead of simple data members like here, there were function pointers to constructors, destructors and clone functions, but I'm only interested if these kind of castings are well defined.
This code compiled and run as expected with gcc and g++.
struct Point
{
int x;
int y;
};
struct Square
{
struct Point *topLeft;
struct Point *bottomRight;
int area;
};
int main()
{
void *square = calloc(1,sizeof(struct Square));
* (struct Point **) square = (struct Point *) calloc(1,sizeof(struct Point));
* ( ( (struct Point **) square) + 1) = (struct Point *) calloc(1,sizeof(struct Point));
struct Square *sqrptr = (struct Square *) square;
sqrptr->topLeft->x = 2;
sqrptr->topLeft->y = 3;
sqrptr->bottomRight->x = 5;
sqrptr->bottomRight->y = 7;
sqrptr->area = 20;
printf("Values: %d %d %d %d\n", (** (struct Point **) square).x,
(** (struct Point **) square).y,
(** ( ( (struct Point **) square) + 1) ).x,
(** ( ( (struct Point **) square) + 1) ).y );
free(sqrptr->topLeft);
free(sqrptr->bottomRight);
free(sqrptr);
}
Also, according to valgrind, there is no memory leaks.
EDIT: I just tried using C++ style castings, g++ doesn't give any error nor warning messages.