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);
}
実際、C99 には uintptr_t と intptr_t があることを認識しています。しかし、教育目的のために、いくつか質問したいと思います。始める前に、これは悪い習慣であり、この方法で行うべきではないことを知っています。
Q1. ケース1は未定義の動作を引き起こす可能性がありますか? 安全ですか?そうでない場合、なぜですか?安全であれば、「case_1」変数が unsigned long int とまったく同じアドレスを保持することが保証されていますか?
Q2. ケース 2 についても同様です。
Q3. ケース3も同様。
Q4.ケース 4 については上記と同じです。