这是我的编译警告:
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 **’
Run Code Online (Sandbox Code Playgroud)
这是相关的源代码:
/* 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);
Run Code Online (Sandbox Code Playgroud)
将非const变量作为const参数传递有什么问题?据我了解,这是为了确保字符串不会在函数内部被修改.那警告为什么会发生呢?
编译器:Windows/Cygwin上的gcc版本4.9.2(GCC)
因为从技术上讲,您可能通过将非const指针传递给const指针参数来破坏承诺.
"带走常识是危险的"
http://c-faq.com/ansi/constmismatch.html
以下是上述链接的内容:
您可以使用指向T的指针(对于任何类型T),其中指向const-T指针.但是,允许在限定指针类型中轻微不匹配的规则(显式异常)不是递归应用的,而是仅在顶层应用.(const char**是指向const-char的指针,因此异常不适用.)
你不能将char**值赋给const char**指针的原因有点模糊.鉴于const限定符完全存在,编译器希望帮助您保证不修改const值.这就是为什么你可以将一个char*分配给一个const char*,而不是另一种方式:对于一个简单的指针来说,"添加"常量显然是安全的,但将它取下来是很危险的.但是,假设您执行了以下更复杂的分配系列:
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
Run Code Online (Sandbox Code Playgroud)
在第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**)),尽管一如既往需要这样的演员可能表示演员没有真正解决的更深层次的问题.