放弃函数参数的常量是否是未定义行为?
想象一下,我有这个 C 函数(以及头文件中的相应原型),
void clearstring(const char *data) {
char *dst = (char *)data;
*dst = 0;
}
上面的代码中是否存在未定义的行为,将 const
转换掉,或者只是一个可怕的行为不好的编程习惯?
假设没有使用 const 限定的对象
char name[] = "pmg";
clearstring(name);
Imagine I have this C function (and the corresponding prototype in a header file)
void clearstring(const char *data) {
char *dst = (char *)data;
*dst = 0;
}
Is there Undefined Behaviour in the above code, casting the const
away, or is it just a terribly bad programming practice?
Suppose there are no const-qualified objects used
char name[] = "pmg";
clearstring(name);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果调用者向您传递一个指向 const 对象的指针或指向字符串文字的指针,则尝试写入
*dst
是 UB 。但是,如果调用者向您传递一个指向实际上可变的数据的指针,则行为就被定义了。创建指向可修改
char
的const char*
并不会使该char
不可变。所以:
也就是说,你的函数是非常不明智的,因为调用者很容易导致UB。但实际上可以将其用于定义的行为。
The attempt to write to
*dst
is UB if the caller passes you a pointer to a const object, or a pointer to a string literal.But if the caller passes you a pointer to data that in fact is mutable, then behavior is defined. Creating a
const char*
that points to a modifiablechar
doesn't make thatchar
immutable.So:
That is, your function is extremely ill-advised, because it is so easy for a caller to cause UB. But it is in fact possible to use it with defined behavior.
考虑像 strstr 这样的函数,如果给定一个指向包含字符串的对象的一部分的指针,则返回一个指向同一对象的可能不同部分的指针。如果该方法传递一个指向只读内存区域的指针,它将返回一个指向只读内存区域的指针;同样,如果给它一个指向可写区域的指针,它将返回一个指向可写区域的指针。
在 C 中,无法让函数在给定
const char *
时返回const char *
,并在给定const char *
时返回普通char *
给定一个普通的char *
。为了与strstr
在 const char * 的概念被添加到该语言之前的工作方式兼容,它必须将 const 限定的指针转换为非 const 限定的指针。 -const 限定指针。虽然作为库函数strstr
确实可能有权执行此类转换,即使用户代码不能,但相同的模式在用户代码中经常出现,因此禁止它是可行的。Consider a function like
strstr
which, if given a pointer to a part of an object containing a string, with return a pointer to a possibly-different part of the same object. If the method is passed a pointer to a read-only area of memory, it will return a pointer to a read-only area of memory; likewise if it is given a pointer to a writable area, it will return a pointer to a writable area.There is no way in C to have a function return a
const char *
when given aconst char *
, and return an ordinarychar *
when given an ordinarychar *
. In order to be compatible with the waystrstr
worked before the idea of aconst char *
was added to the language, it has to convert a const-qualified pointer into a non-const-qualified pointer. While it's true that as a library functionstrstr
might be entitled to do such a cast even if user code could not, the same pattern comes up often enough in user code that it would be practical to forbid it.