【问题标题】:c compiler warning when passing a char *arr[] to a function as const char **arr将 char *arr[] 作为 const char **arr 传递给函数时的 c 编译器警告
【发布时间】:2014-09-03 02:36:20
【问题描述】:

代码如下:

#include <stdio.h>

void test(const char* anagrams[])
{
    while(*anagrams != NULL) {
        printf("%s\n", *anagrams);
        anagrams++;
    }
}

int main()
{
    char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};

    printf("%lu\n", sizeof(arr));
    test(arr);
}

此代码生成以下警告:

$ gcc const_char_star_star.c

const_char_star_star.c:16:8: warning: passing 'char *[8]' to parameter of type 'const    char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]

test(arr);
   ^~~
const_char_star_star.c:3:23: note: passing argument to parameter 'anagrams' here
void test(const char* anagrams[])
                  ^

生成 1 个警告。

如果我删除测试参数中的 const 限定符,它会在没有任何警告的情况下编译。

【问题讨论】:

  • 附带说明:将函数参数用作这样的变量并不是一个好习惯,如果函数更复杂,可能会更难理解。最好声明一个复制参数并保持原始不变的局部变量。无论如何优化都会在后台为您解决它。
  • printf("%zu\n", sizeof(arr)); :将"%zu" 用于sizeof 或(size_t)。

标签: c pointers char constants


【解决方案1】:

关键字const表示变量所持有的值不能改变。 这里

char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};  
test(arr);

函数test定义为

void test(const char* anagrams[])

这表示指针指向的值不能改变,所以函数不能改变数组的原始值

编译器会生成警告,因为在调用函数 test(arr); 时它没有指定数组 'arr' 是一个 const 二维数组,这会产生歧义,因为主函数中使用的 char* 数组作为 const char* 传递给编译器,因此会生成您指定的警告。

Inode 避免警告声明数组为

const char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};

【讨论】:

  • 感谢您的解释。我的意图不是将 arr 定义为 const,但不应允许函数测试对其进行修改。这样做的正确方法是什么?
【解决方案2】:

复制:

Double pointer const-correctness warnings in C

在 C 常见问题解答中回答:

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

复制粘贴示例:

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 行被禁止的原因。

【讨论】:

    【解决方案3】:

    正如你自己指出的那样,这是一个限定符问题;

    const char *arr[] = {"cat", "bat", "mate", "tac", "tab", "act", "tame", NULL};
    

    在声明中添加const 也会使警告消失。

    【讨论】:

    • 顺便说一句,注意warnings 做得很好——他们有时会出现更重要。
    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 2013-05-16
    相关资源
    最近更新 更多