从不兼容的指针类型获取初始化的上下文

时间:2017-12-21 02:56:36

标签: c gcc

编译时,我已经多次遇到此错误:

[
[
    "1507104333940",
    209.231
],
[
    "1507104333950",
    208.715
],
[
    "1507104333960",
    207.933
],
[
    "1507104333970",
    207.112
],
[
    "1507104333980",
    206.634
],
[
    "1507104333990",
    206.638
],
[
    "1507104334000",
    206.132
],
[
    "1507104334010",
    205.197
],
[
    "1507104334020",
    204.713
],
[
    "1507104334030",
    204.415
]]

保险丝的文档往往不一致和稀疏,所以我在GitHub上查找其他文件系统实现以找到正确的方法签名。

在这种情况下,我的问题是:

gcc -o index.o -c -D_FILE_OFFSET_BITS=64 "-D FUSE_USE_VERSION=31" index.c
index.c:40:12: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
   .write = o_write,
            ^~~~~~~

应该是

int o_write(const char*, char*, size_t, off_t, struct fuse_file_info*);

我的问题是:

当我看到这个警告时,是否有一种简单的方法可以知道所谓指针类型是什么?我花了很多时间追踪a proper implementation in sshfs,但我觉得有一种更简单的方法。

1 个答案:

答案 0 :(得分:3)

这或多或少是MCVE(Minimal, Complete, Verifiable Example),它会重现您显示的错误消息:

#include <sys/types.h>      // size_t, off_t

struct fuse_file_info;

struct whatever
{
    int (*write)(const char*, const char*, size_t, off_t, struct fuse_file_info*);
};

extern int o_wrong(const char*, char*, size_t, off_t, struct fuse_file_info*);
extern int o_write(const char*, const char*, size_t, off_t, struct fuse_file_info*);

struct whatever v1 = { .write = o_wrong };
struct whatever v2 = { .write = o_write };

当包含所显示代码的文件fuse37.c使用GCC 7.2.0编译时(在运行macOS High Sierra 10.13.2的Mac上),我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c fuse37.c
fuse37.c:13:33: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
 struct whatever v1 = { .write = o_wrong };
                                 ^~~~~~~
fuse37.c:13:33: note: (near initialization for ‘v1.write’)
cc1: all warnings being treated as errors
$

&#39;注释中的辅助信息&#39; line告诉您需要查找write成员(结构类型struct whatever)的定义。

当您将错误的类型参数传递给函数调用时,您会得到更好的消息:

$ cat fuse47.c
    struct gizmotron;
    struct megatron;

    extern void calumniator(struct gizmotron *ptr);
    extern void transformer(struct megatron *arg);

    void calumniator(struct gizmotron *ptr)
    {
        transformer(ptr);
    }
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -c fuse47.c
fuse47.c: In function ‘calumniator’:
fuse47.c:9:17: error: passing argument 1 of ‘transformer’ from incompatible pointer type [-Werror=incompatible-pointer-types]
     transformer(ptr);
                 ^~~
fuse47.c:5:13: note: expected ‘struct megatron *’ but argument is of type ‘struct gizmotron *’
 extern void transformer(struct megatron *arg);
             ^~~~~~~~~~~
cc1: all warnings being treated as errors
$

现在您可以看到该注释是明确的预期类型和收到的类型。我不确定初始化中是否缺少额外信息(与函数调用相反)是故意还是疏忽。由于一次诊断是可能的,另一种也应该是。可能值得询问GCC维护团队是否可以升级。