You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C23中用_Generic实现支持右值的IS_POINTER(p)宏?

用_Generic实现支持右值指针的IS_POINTER宏

原宏的问题在于尝试取右值指针的地址,而C标准不允许对右值取地址。可以通过以下方式改写宏,避免直接取P的地址:

#define IS_POINTER(P) \
  _Generic( (P), \
    typeof(&*P): 1, \
    default: 0 \
  )

原理说明

  • 对于指针类型(包括左值指针和右值指针,比如int* p或&i):*P会得到指针指向的左值,&*P的类型与P本身的类型完全一致,因此_Generic会匹配typeof(&*P)分支,返回1。
  • 对于数组类型(比如int a[1]):*a是数组首元素的左值,&*a的类型是元素指针(如int*),与数组本身的类型(int[1])不匹配,因此进入default分支,返回0。
  • 对于非指针非数组的基本类型(比如int i):&*i的类型是对应指针类型(如int*),与原类型(int)不匹配,进入default分支,返回0。

测试验证

#include <stdio.h>

#define IS_POINTER(P) \
  _Generic( (P), \
    typeof(&*P): 1, \
    default: 0 \
  )

int main() {
  int i;
  int a[1];
  int *p = &i;
  void (*pf)(void) = NULL;

  printf("IS_POINTER(a) = %d\n", IS_POINTER(a));    // 输出0,正确
  printf("IS_POINTER(p) = %d\n", IS_POINTER(p));    // 输出1,正确
  printf("IS_POINTER(&i) = %d\n", IS_POINTER(&i));  // 输出1,正确
  printf("IS_POINTER(i) = %d\n", IS_POINTER(i));    // 输出0,正确
  printf("IS_POINTER(pf) = %d\n", IS_POINTER(pf));  // 输出1,正确
  return 0;
}

内容的提问来源于stack exchange,提问作者Paul J. Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:15:14