use*_*008 15 c const const-char std c-strings
似乎strtol()并且strtod()有效地允许(并强制)你在字符串中抛弃constness:
#include <stdlib.h>
#include <stdio.h>
int main() {
const char *foo = "Hello, world!";
char *bar;
strtol(foo, &bar, 10); // or strtod(foo, &bar);
printf("%d\n", foo == bar); // prints "1"! they're equal
*bar = 'X'; // segmentation fault
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面,我自己没有演出.然而,strtol()基本上把我const char *变成了一个char *对我来说,没有任何警告或任何东西.(事实上,它不会让你输入bar的const char *,所以迫使类型的不安全的变化.)是不是真的很危险?
Ada*_*eld 14
我猜这是因为替代方案更糟糕.假设原型已更改为添加const:
long int strtol(const char *nptr, const char **endptr, int base);
Run Code Online (Sandbox Code Playgroud)
现在,假设我们要解析一个非常量字符串:
char str[] = "12345xyz"; // non-const
char *endptr;
lont result = strtol(str, &endptr, 10);
*endptr = '_';
printf("%s\n", str); // expected output: 12345_yz
Run Code Online (Sandbox Code Playgroud)
但是当我们尝试编译这段代码时会发生什么?编译错误!这是非直观的,但你不能隐含地将a转换char **为a const char **.有关原因的详细说明,请参阅C++ FAQ Lite.它在技术上谈论C++有,但是论据同样适用于C.在C/C++,你只允许隐式转换从"指针类型 "为"指针const 类型 "的最高境界:转换即可执行是从char **到char * const *,或等同地从"指针(指针char)"到"指针(const指针char)".
因为我猜想解析一个非常量字符串比解析一个常量字符串更有可能,我会继续假设 - 不const正确的情况下的不正确性比使常见情况成为编译器错误更可取.
是的,其他函数具有相同的"常量清洗"问题(例如strchr,strstr,所有那些).
正是由于这个原因,C++增加了重载(21.4:4):函数签名strchr(const char*, int)被两个声明所取代:
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
Run Code Online (Sandbox Code Playgroud)
但是当然在C语言中你不能同时拥有两个具有相同名称的const-correct版本,所以你得到了const-incorrect的妥协.
C++没有提到strtol和strtod的类似重载,实际上我的编译器(GCC)没有它们.我不知道为什么不:你不能隐式char**转换const char**(连同没有重载)的事实解释了C,但我不太清楚C++重载会出现什么问题:
long strtol(const char*, const char**, int);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4886 次 |
| 最近记录: |