uintptr_t dan intptr_t adalah tipe numerik yang cukup besar untuk memuat pointer, pertanyaan saya adalah bagaimana mereka berhubungan dengan tipe numerik lain saat casting ke arah mereka. Khususnya jenis mana (int, long, long long, short, char, size_t dll.) yang tidak dapat NUM_TYPE didefinisikan agar fungsi selanjutnya tidak merusak nilai n?

intptr_t cast_num(NUM_TYPE n){return (intptr_t) n;}
1
afiori 1 Juli 2020, 14:09

2 jawaban

Jenis opsional:

intptr_t memiliki rentang setidaknya [-0x7FFF...0x7FFF].

uintptr_t memiliki rentang [0... setidaknya 0xFFFF].


Gunakan INTPTR_MIN, INTPTR_MAX, UINTPTR_MAX dari <stdint.h> untuk membentuk kode kondisi sesuai kebutuhan.

intptr_t cast_long(unsigned long n) {
  _Static_assert(UIINTPTR_MAX >= ULONG_MAX, "unsigned long too big"): 
  return (intptr_t) n;
}

Catatan: Pointer objek ke/dari uintptr_t dan intptr_t harus dikonversi melalui void *. Pointer fungsi mungkin terlalu besar.

1
chux - Reinstate Monica 1 Juli 2020, 17:07

Itu tergantung untuk apa Anda membutuhkannya. Tipe integer (hampir) apa pun yang tidak lagi dapat dikonversi dengan aman.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define CCAST(NUM_TYPE )int cast_num ## NUM_TYPE (NUM_TYPE n, intptr_t *intptr){ *intptr = (intptr_t)n; return sizeof(n) > sizeof(*intptr);}
#define UCAST(NUM_TYPE, x, result)   cast_num ## NUM_TYPE (x, &(result))

CCAST(uint32_t)
CCAST(uint64_t)

int foo(uint64_t x, uint32_t y)
{
    volatile intptr_t iptr;
    volatile int result1 = UCAST(uint32_t, y, iptr);
    volatile int result2 = UCAST(uint64_t, x, iptr);
}

https://godbolt.org/z/BkEzXA

0
P__J__ 1 Juli 2020, 11:48