c++ - 为什么有些库使用非常量 char * 作为函数参数?

标签 c++ c libs

有时在我的 C++ 项目中使用纯 C 库,我会看到奇怪的(在我看来)函数声明。

例如:libldap 的 ldap_search_ext():https://linux.die.net/man/3/ldap_search_ext_s

int ldap_search_ext(
       LDAP *ld,
       char *base,
       int scope,
       char *filter,
       char *attrs[], // this one!
       int attrsonly,
       LDAPControl **serverctrls,
       LDAPControl **clientctrls,
       struct timeval *timeout,
       int sizelimit,
       int *msgidp );

为什么 attrs[] 不能是 const char *

这样的声明不想改变指针的内容并产生很多问题:

// pure C
void func(char * data[])
{
  ...
}

func({"blabla"}); // won't work (corrected: yes, this is wrong syntax, but it's true for structs of pointers)

const char *d[] = {"blabla", "blablu"};
func(d); // won't work

// C++
const std::string str("blabla");
char * data[] = { str.data() }; // even non-const won't work (because data() returns const*)
/// etc...

是否有任何理由不将此类参数声明为 const?

最佳答案

这主要是(由于)C 标准中的一个历史缺陷,它从未被修复。

const 被添加到 C 时,隐式(安全地)转换简单指针的能力被添加了——你可以隐式地将 T * 转换为 const T * 就好了。但是,更复杂的指针类型的(安全)转换被遗漏了——您不能将 T * const * 转换为 const T * const *。因此,当一个库采用这样的双指针时,如果它是只读的,它没有任何“好”的方法来使它成为const。将其设为 const char **const char * const * 会破坏某些用途(需要凌乱的显式转换)。

请注意,允许将 T ** 隐式转换为 const T ** 是不安全的——这样的指针可用于修改 T * 以指向一个 const T * 而无需强制转换。

关于c++ - 为什么有些库使用非常量 char * 作为函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67777660/

相关文章:

c++ - 是什么导致我的 2D Perlin 噪声中出现这些伪像?

c++ - const 参数问题

c++ - 如何从 void 函数中获取值?

.net - TCP 慢启动算法是许多单个文件传输缓慢的原因吗?

C++ Cassandra 构建错误

java-native-interface - 在设备上找不到 Gradle native 库,但存在于 apk 中

c++ - 忽略头文件中的 main

c++ - Cppcheck 静态代码分析器能否真正检测到不太常见的警告,如 "Relative Path Traversal (CWE-23)"或 "Buffer Under-read(CWE-127)"?

c - 二进制文件并向其中写入结构

Python - libs 子文件夹的用途是什么?