我已阅读C FAQ on const,但我仍感到困惑。
我的(显然是错误的)印象是函数声明中的const本质上是一个承诺,函数不会修改你标记为const的内容。因此传入const或not-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 **'
答案 0 :(得分:2)
标准禁止这样做,因为这样会违反对象的常量。考虑:
<asp:CheckBox ID="CurrentCheckBox" runat="server" AutoPostBack="True" Checked='<%# Bind("BDValue") %>' OnCheckedChanged="SharedFunctionForThisCheckBox_CheckedChanged" onclick="checkBoxConfirmClick(this);" />
<script type="text/javascript">
function checkBoxConfirmClick(elementRef) {
if (elementRef.checked) {
if (window.confirm('Are you sure?') == false)
elementRef.checked = false;
}
}
</script>
这一行之后:
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*
)。然后,使用char*
指向const对象,这会自动使ch_pptr
指向相同的内存位置。通过这样做,您允许对对象进行任何修改(使用ch_ptr
),该对象最初被声明为常量。
这个错误是非常微妙的,但过了一段时间,你应该能够理解为什么它可能是危险的。这就是不被允许的原因。
是的,但是为什么不把函数声明中的const作为函数不做那种邪恶的“承诺”?
因为它以相反的方式工作 - 函数,完全合法的事情可能会引入无效的行为。看看这段代码:
ch_ptr
答案 1 :(得分:0)
f2( v1 ); /* compiler warning - why? */
编译器警告 - 为什么?
因为char**
和const char**
不同。它们不被视为相同。
char** v1 // pointer to pointer to char
您可以在此更改**v1
的值。
而
const char** v2 //pointer to pointer to constant char
在这里,您无法更改**v2
的值,如果您尝试编译器发出错误。