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

喜欢而已 提交于 2020-11-27 19:42:44

问题


Here is the compile warning i have:

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 **’

Here is the relevant source code:

/* 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);

What is wrong with passing a non const variable as a const parameter ? To my understanding, this is to make sure the string wont be modified inside the function. So why is the warning occuring ?

Compiler: gcc version 4.9.2 (GCC) on Windows/Cygwin


回答1:


Because technically you may be breaking a promise by passing a non-const pointer into a const pointer parameter.

"It is dangerous to take away const-ness"

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

Here is the content of the above link:

You can use a pointer-to-T (for any type T) where a pointer-to-const-T is expected. However, the rule (an explicit exception) which permits slight mismatches in qualified pointer types is not applied recursively, but only at the top level. (const char ** is pointer-to-pointer-to-const-char, and the exception therefore does not apply.)

The reason that you cannot assign a char ** value to a const char ** pointer is somewhat obscure. Given that the const qualifier exists at all, the compiler would like to help you keep your promises not to modify const values. That's why you can assign a char * to a const char *, but not the other way around: it's clearly safe to ``add'' const-ness to a simple pointer, but it would be dangerous to take it away. However, suppose you performed the following more complicated series of assignments:

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

In line 3, we assign a char ** to a const char **. (The compiler should complain.) In line 4, we assign a const char * to a const char *; this is clearly legal. In line 5, we modify what a char * points to--this is supposed to be legal. However, p1 ends up pointing to c, which is const. This came about in line 4, because *p2 was really p1. This was set up in line 3, which is an assignment of a form that is disallowed, and this is exactly why line 3 is disallowed.

Assigning a char ** to a const char ** (as in line 3, and in the original question) is not immediately dangerous. But it sets up a situation in which p2's promise--that the ultimately-pointed-to value won't be modified--cannot be kept.

(C++ has more complicated rules for assigning const-qualified pointers which let you make more kinds of assignments without incurring warnings, but still protect against inadvertent attempts to modify const values. C++ would still not allow assigning a char ** to a const char **, but it would let you get away with assigning a char ** to a const char * const *.)

In C, if you must assign or pass pointers which have qualifier mismatches at other than the first level of indirection, you must use explicit casts (e.g. (const char **) in this case), although as always, the need for such a cast may indicate a deeper problem which the cast doesn't really fix.



来源:https://stackoverflow.com/questions/28783534/expected-expected-const-char-but-argument-is-of-type-char

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!