[英]Why do some libs use non-const char * as function argument?
Sometimes using pure-C libs in my C++ projects, I see strange (in my opinion) function declarations.有时在我的 C++ 项目中使用纯 C 库,我看到奇怪的(在我看来)function 声明。
Eg: libldap's ldap_search_ext() : https://linux.die.net/man/3/ldap_search_ext_s例如: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 );
Why can't attrs[] be a const char *
?为什么 attrs[] 不能是
const char *
?
Declarations like this don't want to change the content of the pointer and generate a lot of issues:像这样的声明不想改变指针的内容并产生很多问题:
// 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...
Is there any reason for not declaring such arguments as const?有什么理由不将这样的 arguments 声明为 const 吗?
This is mostly just (due to) a historical wart in the C standard that has never been fixed.这主要只是(由于)C 标准中的一个历史缺陷,该标准从未得到修复。
When const
was added to C, the ability to implictly (and safely) convert simple pointers was added -- you can implicitly convert a T *
to a const T *
just fine.当
const
添加到 C 时,添加了隐式(并且安全地)转换简单指针的能力——您可以隐式地将T *
转换为const T *
就好了。 However, (safe) conversion of more complex pointer types was missed -- you can't convert a T * const *
to a const T * const *
.但是,错过了更复杂指针类型的(安全)转换——您不能将
T * const *
转换为const T * const *
。 As a result, when a library takes a double pointer like this, it does not have any 'good' way of making it const
if it is read only.结果,当一个库采用这样的双指针时,如果它是只读的,它就没有任何“好”的方法使它成为
const
。 Making it either a const char **
or a const char * const *
would break some uses (requiring messy explicit casts).将其
const char **
或const char * const *
会破坏某些用途(需要混乱的显式强制转换)。
Note that allowing implicit conversions of T **
to const T **
would be unsafe -- such a pointer could be used to modify a T *
to point at a const T *
without a cast.请注意,允许将
T **
隐式转换为const T **
是不安全的——这样的指针可用于修改T *
以指向不强制转换的const T *
。
One likely reason is that string constants in C (unlike C++) are not const
.一个可能的原因是 C(与 C++ 不同)中的字符串常量不是
const
。
As such, there was a historical lack of const-correctness in many libraries that should have been there.因此,在许多本应存在的库中,历史上都缺乏 const 正确性。 Had string constants been
const
, programmers would have been forced to account for it.如果字符串常量是
const
,程序员将不得不考虑它。
When dealing with libraries such as this that you know don't modify the argument, you have to apply a const_cast
to make it fit.在处理诸如此类您知道不修改参数的库时,您必须应用
const_cast
以使其适合。
char *d[] = {const_cast<char *>("blabla"), const_cast<char *>("blablu")};
func(d);
const std::string str("blabla");
char * data[] = { const_cast<char *>(str.data()) };
func(data);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.