expected 预期‘const char **’但参数类型为‘char **’

expected expected ‘const char **’ but argument is of type ‘char **’

这是我的编译警告:

src/Debugger.c:219:52: warning: passing argument 2 of ‘Debugger_Command[i].Callback’ from incompatible pointer type
                 Debugger_Command[i].Callback(argc, argv);
                                                    ^
src/Debugger.c:219:52: note: expected ‘const char **’ but argument is of type ‘char **’

相关源码如下:

/* Definition */
typedef void (*Debugger_Callback_t)(int argc, char const * argv[]);
typedef struct tagDebugger_Command_t {
    /* ... */
    Debugger_Callback_t Callback;   /**< Callback */
} Debugger_Command_t;
Debugger_Command_t const Debugger_Command[] = { /* ... */ }

/* Use of the callback where the warning occurred */
char *argv[DEBUGGER_ARG_COUNT];
Debugger_Command[i].Callback(argc, argv);

将非 const 变量作为 const 参数传递有什么问题? 据我了解,这是为了确保字符串不会在函数内部被修改。那么为什么会出现警告?

编译器:Windows/Cygwin

上的 gcc 版本 4.9.2 (GCC)

因为从技术上讲,将非常量指针传递给常量指针参数可能会违反承诺。

"It is dangerous to take away const-ness"

http://c-faq.com/ansi/constmismatch.html

这里是上面link的内容:

您可以在需要指向常量 T 的指针的地方使用指向 T 的指针(对于任何类型 T)。然而,允许限定指针类型轻微不匹配的规则(显式例外)不会递归应用,而只会在顶层应用。 (const char ** 是指针到指针到 const-char,因此例外不适用。)

不能将 char ** 值赋给 const char ** 指针的原因有些晦涩。鉴于 const 限定符完全存在,编译器希望帮助您信守不修改 const 值的承诺。这就是为什么你可以将一个 char * 分配给一个 const char *,而不是相反:将 const-ness ‘添加’到一个简单的指针显然是安全的,但将它拿走是危险的。但是,假设您执行了以下更复杂的一系列作业:

const char c = 'x';    /* 1 */
char *p1;              /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c;              /* 4 */
*p1 = 'X';             /* 5 */

在第 3 行,我们将一个 char ** 分配给一个 const char **。 (编译器应该会抱怨。)在第 4 行,我们将一个 const char * 分配给一个 const char *;这显然是合法的。在第 5 行,我们修改了 char * 指向的内容——这应该是合法的。但是,p1 最终指向 c,它是 const。这发生在第 4 行,因为 *p2 实际上是 p1。这是在第 3 行设置的,这是不允许的形式的赋值,这正是第 3 行不允许的原因。

将 char ** 分配给 const char **(如第 3 行和原始问题中所示)不会立即产生危险。但它造成了 p2 的承诺——最终指向的值不会被修改——无法保持的情况。

(C++ 有更复杂的规则来分配 const 限定的指针,这使您可以进行更多类型的分配而不会引起警告,但仍然可以防止无意中尝试修改 const 值。C++ 仍然不允许分配 char **到一个 const char **,但它会让你摆脱分配一个 char ** 到一个 const char * const *.)

在 C 中,如果您必须分配或传递在第一级间接级别以外的限定符不匹配的指针,则必须使用显式强制转换(例如,在这种情况下为 (const char **)),尽管一如既往,需要这样的演员阵容可能表明演员阵容并没有真正解决的更深层次的问题。