size_t size_int = sizeof(unsigned long int);
size_t size_ptr = sizeof(void*);
printf("sizeof(unsigned long int): %zu\n", size_int);
printf("sizeof(void*): %zu\n", size_ptr);
if(size_int == size_ptr) {
int a = 0;
void * ptr_a = &a;
// case 1
unsigned long int case_1 = *((unsigned long int*)&ptr_a);
printf("case 1: %lu\n", case_1);
// case 2
unsigned long int case_2 = (unsigned long int)ptr_a;
printf("case 2: %lu\n", case_2);
// case 3
unsigned long int case_3 = 0;
memcpy(&case_3, &ptr_a, sizeof(void*));
printf("case 3: %lu\n", case_3);
// case 4
void *ptr_b = NULL;
memcpy(&ptr_b, &case_3, sizeof(void*));
int *ptr_c = (int*)ptr_b;
*ptr_c = 5;
printf("case 5: %i\n", a);
}
In fact I am aware that there are uintptr_t and intptr_t in C99. However, for educational purposes I want to ask some questions. Before I start, I know that it is a bad practice and should never be done in this way.
Q1. Could case 1 cause an undefined behaviour? Is it safe? If it is not, why? If it is safe, is it guaranteed that "case_1" variable holds exactly the same address as an unsigned long int?
Q2. Same above for case 2.
Q3. Same above for case 3.
Q4. Same above for case 4.