是否未定义行为抛弃函数参数的常量?

想象一下,我有这个C函数(以及头文件中的相应原型)

void clearstring(const char *data) { char *dst = (char *)data; *dst = 0; } 

在上面的代码中是否存在未定义的行为, const ,或者它只是一个非常糟糕的编程实践?

假设没有使用const限定对象

 char name[] = "pmg"; clearstring(name); 

如果调用者向您传递指向const对象的指针或指向字符串文字的指针, 尝试写入*dst是UB。

但是如果调用者向您传递指向实际上是可变的数据的指针,则定义行为。 创建指向可修改charconst char*不会使该char不可变。

所以:

 char c; clearstring(&c); // OK, sets c to 0 char *p = malloc(100); if (p) { clearstring(p); // OK, p now points to an empty string free(p); } const char d = 0; clearstring(&d); // UB clearstring("foo"); // UB 

也就是说,你的function非常不明智,因为调用者很容易导致UB。 但实际上可以将它与定义的行为一起使用。

考虑像strstr这样的函数,如果给出指向包含字符串的对象的一部分的指针,则返回指向同一对象的可能不同部分的指针。 如果该方法被传递给指向只读存储区的指针,它将返回一个指向只读存储区的指针; 同样,如果给出一个指向可写区域的指针,它将返回一个指向可写区域的指针。

C中没有办法让一个函数在给定一个const char *时返回一个const char * ,并在给定一个普通的char *时返回一个普通的char * 。 为了在将const char *的概念添加到语言之前与strstr工作的方式兼容,它必须将const限定的指针转换为非const限定的指针。 虽然确实如果库函数strstr可能有权进行这样的转换,即使用户代码不能,但是在用户代码中经常出现相同的模式,禁止它是实用的。