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

使用void*时如何从数字字面量获取内存地址(指针)?

问题背景与描述

背景

我在程序中使用通用void*指针,因为它统一、高效,能根据上下文转换为任意类型。调用比较函数时,所有参数必须以void*传递,示例代码:

compare_integer_equal((void*) &r, p12, (void*) NUMBER_1_INTEGER_STATE_CYBOI_MODEL);

其中整数常量的全局定义为:

static int NUMBER_1_INTEGER_STATE_CYBOI_MODEL_ARRAY[] = { 1 };
static int* NUMBER_1_INTEGER_STATE_CYBOI_MODEL = NUMBER_1_INTEGER_STATE_CYBOI_MODEL_ARRAY;

问题

这类常用数字的全局常量总文件大小已超2MB,想要消除这部分占用。虽然可以用局部变量:

int i = 1;
compare_integer_equal((void*) &r, p12, (void*) &i);

但数百次比较时,不想承担局部变量的额外内存和时间开销。尝试直接取字面量的地址会触发编译器错误:lvalue required as unary ‘&’ operand,示例:

compare_integer_equal((void*) &r, p12, (void*) &1);

请问:

  • 是否有方法从字面量获取内存地址(指针)?
  • 还有其他将字面量作为void*处理的思路吗?

解决方案

1. 使用静态局部常量(单实例复用)

在调用比较函数的函数内部,定义static const修饰的局部常量。编译器会保证它仅在第一次调用时初始化,后续复用同一个内存地址,既避免全局变量的空间浪费,也不会产生重复创建变量的开销:

// 函数内部定义,仅初始化一次
static const int num_1 = 1;
compare_integer_equal((void*) &r, p12, (void*) &num_1);

这种方式下,每个字面量只会生成一个内存实例,且仅在当前函数范围内可见,不会污染全局命名空间,可执行文件体积远小于全局数组+指针的实现。

2. 利用C99复合字面量

C99标准支持的复合字面量可以直接创建匿名常量实例,无需显式定义变量就能取其地址作为void*传递:

compare_integer_equal((void*) &r, p12, (void*) &(const int){1});

复合字面量的生命周期:函数内使用时与自动变量一致,全局作用域使用时与全局变量一致。对于频繁调用的场景,编译器通常会自动优化,避免重复实例化的开销。

3. 封装比较函数,支持直接传字面量

如果允许修改接口或新增封装,可以用宏实现兼容,让调用方直接传字面量,内部完成指针转换:

// 保留原函数兼容旧代码
int compare_integer_equal(void* a, void* b, void* c);

// 封装宏,自动创建临时常量
#define COMPARE_INTEGER_EQUAL(a, b, val) \
    do { \
        const int tmp = (val); \
        compare_integer_equal((a), (b), (void*)&tmp); \
    } while(0)

// 调用方式更简洁
COMPARE_INTEGER_EQUAL((void*)&r, p12, 1);

编译器会对临时变量做优化,实际运行开销几乎可忽略,同时提升代码可读性。

4. 直接转换字面量为void*(仅限特定场景)

如果compare_integer_equal内部实际是将void*转换为整数类型比较(而非解引用指针访问内存),可以直接把字面量强制转换为void*:

compare_integer_equal((void*) &r, p12, (void*) (intptr_t)1);

警告:这种方式仅适用于函数逻辑处理指针数值的场景,若函数需要解引用指针,会触发未定义行为,必须确认函数实现后再使用。


内容的提问来源于stack exchange,提问作者Christian Heller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:58:24