有时在我的 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/