我已经阅读了 Why does passing char** as const char** generate a warning? ,但我仍然很困惑。
我有这样的印象(显然是错误的):函数声明中的 const 本质上是一个 promise ,即该函数不会修改您标记为 const 的内容。因此传入 const 或非 const 参数就可以了。但这:
#include <stdio.h>
extern void f1 ( const char * cc );
extern void f2 ( const char ** ccc );
int main ( void ) {
char c1[] = "hello";
const char * c2 = "hello";
char * c3 = NULL;
char ** v1 = NULL;
const char ** v2 = NULL;
f1( c1 ); /* ok */
f1( c2 ); /* ok */
f1( c3 ); /* ok */
f1( "hello, world" ); /* ok */
f2( v1 ); /* compiler warning - why? */
f2( v2 ); /* ok */
return 0;
}
如此警告:
$ cc -c -o sample.o sample.c sample.c: In function 'main': sample.c:17:
warning: passing argument 1 of 'f2' from incompatible pointer type
sample.c:4: note: expected 'const char **' but argument is of type 'char **'
最佳答案
标准禁止这样做,因为这会违反对象的常量性。考虑:
const char ch = 'X';
char* ch_ptr;
const char** ch_pptr = &ch_ptr; // This is not allowed, because...
*ch_pptr = &ch;
*ch_ptr = 'Q'; // ...this will modify ch, which should be immutable!
此行之后:
const char** ch_pptr = &ch_ptr;
*ch_pptr
和 ch_ptr
产生相同的值(地址),但它们具有不同的类型(const char*
和 字符*
)。然后,您使用 ch_pptr 指向 const 对象,这会自动导致 ch_ptr 指向相同的内存位置。通过这样做,您允许对最初声明为常量的对象进行任何修改(使用ch_ptr
)。
这个错误非常微妙,但是过了一段时间,您应该能够理解为什么它可能很危险。这就是为什么它是不允许的。
Yes, but why is not putting the const in the function declaration the "promise" that the function does not do that sort of evil?
因为它以相反的方式工作——函数,做完全合法的事情可能会引入无效的行为。看一下这段代码:
static const char* sample_string = "String";
void f2 (const char ** ccc)
{
*ccc = sample_string; //Perfectly valid - function does not do any "evil" things
}
int main ( void )
{
char** v1 = NULL;
f2(v1); // After this call, *v1 will point to sample_string
(*v1)[0] = 'Q'; // Access violation error
return 0;
}
关于const char * 与 const char ** 函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32096734/