根据http://www.cplusplus.com/reference/cstdlib/strtol/,此功能有一个签名long int strtol (const char* str, char** endptr, int base).
我想知道,如果它被传递const char *到字符串的开头,它如何设法将其转换为非const指针指向第一个未处理的字符而不作弊?什么是strtol的实现看起来不会执行const_cast?
您如何
strtol在const-correctness下实现?
您不会,因为strtol的定义天生就不const正确。
这是C标准库中的一个缺陷。
有几个标准函数带有一个const char*参数(预期指向字符数组的开头),并返回一个const char*可用于修改该数组的非指针。
strchr 就是一个例子:
char *strchr(const char *s, int c);
Run Code Online (Sandbox Code Playgroud)
例如:
#include <string.h>
int main(void) {
const char *s = "hello";
char *ptr = strchr(s, 'h');
*ptr = 'H';
}
Run Code Online (Sandbox Code Playgroud)
该程序具有未定义的行为。在我的系统上,它死于分段错误。
该问题本身并未发生strchr。它承诺不会修改传递给它的字符串,并且不会。但是它返回一个指针,调用者可以使用该指针对其进行修改。
早在1980年代后期,ANSI C委员会就可以将每个这样的函数分成两个版本,一个作用于const字符数组,另一个作用于非const数组:
char *strchr(char *s, int c);
const char *strcchr(const char *s, int c);
Run Code Online (Sandbox Code Playgroud)
但这将破坏现有的,之前const存在的ANSI前代码。这与C没有创建字符串文字的原因相同const。
继承了大多数C标准库的C ++,通过提供某些函数的重载版本来处理此问题。
底线是,你作为一个C程序员,有责任不修改您定义为对象const。在大多数情况下,该语言可帮助您实施此操作,但并非总是如此。
至于这些函数如何管理返回const指向const数据的非指针,它们可能仅在内部使用强制类型转换(不是const_cast仅在C ++中存在的强制类型转换)。假设它们是用C实现的,这很可能但不是必需的。
最有可能的是它只是使用铸造。
标准库中有许多具有相同属性的函数。牺牲类型安全性而不是简单性可能是原因,因为您不能像 C++ 中那样重载函数。
他们希望程序员承担责任,并且不会编辑endptr例如str字符串文字。
由于类型系统有限,C 对于实际的人来说是实用的语言。