const char *与const char **函数参数

时间:2015-08-19 13:21:02

标签: c gcc-warning

我已阅读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 **'

2 个答案:

答案 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_ptrconst 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的值,如果您尝试编译器发出错误。