代码之家  ›  专栏  ›  技术社区  ›  Fyodor

避免GCC编译器“不兼容的指针类型”警告

  •  0
  • Fyodor  · 技术社区  · 1 年前

    我写了两个函数。一个用于复制的数组 char 类型:

    void char_arr_copy(const char *src, char *dst, int arr_size)
    {
        int i;
        for (i=arr_size-1; i >= 0; src++, dst++, i--)
            *dst = *src;
    }
    

    另一个用于复制的数组 烧焦 地址:

    void word_arr_copy(const char **src, char **dst, int arr_size)
    {
        int i;
        for (i=arr_size-1; i >= 0; src++, dst++, i--)
            *dst = *src;
    }
    

    我认为这是一件重要的事情,要在函数头中向未来的程序读取器表明,该函数不会更改其操作的某些地址的内容。

    当第一个函数进行精细编译时,第二个函数会引起以下警告:

    revert_str_input_arr2.c:30:14: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
       30 |         *dst = *src;
          |              ^
    revert_str_input_arr2.c: In function ‘create_new_word’:
    revert_str_input_arr2.c:44:23: warning: passing argument 1 of ‘word_arr_copy’ from incompatible pointer type [-Wincompatible-pointer-types]
       44 |         word_arr_copy(*word_arr_ptr, tmp, word_arr_size-1);
          |                       ^~~~~~~~~~~~~
          |                       |
          |                       word {aka char **}
    revert_str_input_arr2.c:26:33: note: expected ‘const char **’ but argument is of type ‘word’ {aka ‘char **’}
       26 | void word_arr_copy(const char **src, char **dst, int arr_size)
          |                    ~~~~~~~~~~~~~^~~
    

    据我所知,不能等同于 const address address 这就是我所有警告的来源。很遗憾,因为我在第一次函数中也可以用 const char 烧焦

    因此,解决此问题的唯一方法是省略 const 标识符,对吧?

    所以事实证明,我可以向(未来潜在的程序读者)表明,我不会改变 src 只满足于我的一个功能,而在另一个功能中,我无论如何都做不到?

    2 回复  |  直到 1 年前
        1
  •  3
  •   Lundin    1 年前

    const char **src 这里的“常量正确性”与指向项的(指针)一起 const char 。如果您改为希望指针数组常量正确,则:

    void word_arr_copy (char*const* src, char** dst, int arr_size)
    

    从右到左读取:“指针指向只读指针指向 char ”。

    但是,请考虑这种改进:

    void word_arr_copy (int arr_size, char* dst[arr_size], char*const src[arr_size])
    
        2
  •  1
  •   Toby Speight    1 年前

    你的意思可能是

    void word_arr_copy(const char *const *src, const char **dst, int arr_size)
    

    void word_arr_copy(char *const *src, char **dst, int arr_size)
    

    (取决于元素分别指向常量还是可变字符)。


    顺便说一句,我建议写 dst 首先,它看起来像标准函数,例如 memcpy() (这本身就把目的地放在首位 = 操作员)。这将有助于减少用户的困惑。而且更喜欢 size_t 用于size参数。