我有一个函数,它接受一个指针,但不修改指向的数据,但返回相同的指针或其派生的指针.我可以将指针设置为const:

const void *some_read_only_operation(const void *ptr) {
    // Do work with ptr
    return ptr;
}

然而,这意味着如果我调用该函数,我将无法在没有强制转换的情况下操作结果,即使我传递的指针不是const.相反,如果我将函数中的指针和返回类型设为非const,那么我将需要强制转换来传递指向函数const的任何指针.我会拿回一个非const分的球,所以我已经打破了const分的安全.

有没有办法在不编写两个单独的函数的情况下,用C语言创建一个表示const正确的函数(const in表示const out,非const in表示非const out)?如果不是,我能走多近?

这似乎是以前很可能被问到的那种问题.我试着用const function returnqualifier preserving function这样的关键词搜索重复的内容,但我什么也找不到.

推荐答案

您可以使用_Generic来执行此操作:

/**
 * Cast a pointer to `void *` while keeping qualifiers, e.g.
 *
 *     struct foo *   => void *
 *     const char *   => const void *
 *     volatile int * => volatile void *
 */
#define VOID_CONVERT(ptr) (1 ? (ptr) : (void *)(ptr))

const void *const_fn(const void *ptr) {
    return ptr;
}

void *non_const_fn(void *ptr) {
    // Re-use the const implementation
    return (void *)const_fn(ptr);
}

#define fn(ptr) _Generic(VOID_CONVERT(ptr), \
    void *: non_const_fn((void *)(ptr)), \
    const void *: const_fn((const void *)(ptr)))

C++相关问答推荐

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

你能用自己的地址声明一个C指针吗?

POSIX文件描述符位置

为什么下面的C代码会进入无限循环?

如何将字符串argv[]赋给C中的整型数组?

警告:C++中数组下标的类型为‘char’[-Wchar-subpts]

从纯C中访问通用项对话框

如何将长字符串转换为较小的缩写,该缩写由第一个字符、最后一个字符和中间的字符数组成?

自定义变参数函数的C预处置宏和警告 suppress ?

将数据移动到寄存器时出现分段故障

实现简单字典时C语言中的段错误

Sizeof(&Q;字符串&Q;)的正确输出是什么?

函数的限制限定指针参数允许优化调用方函数吗?

等同于铁 rust 的纯C语言S未实现!()宏

如何将另一个数组添加到集合中,特别是字符串?

Boyer Moore算法的简单版本中的未定义行为

这段代码用于在C中以相反的顺序打印数组,但它不起作用

如何在zOS上编译共享C库

使用C++中的字符串初始化 struct 时,从‘char*’初始化‘char’使指针变为整数,而不进行强制转换

为什么这个代码的最后一次迭代不能正常工作?