C 中签名的编译器错误

Compiler error for signedness in C

我是 C 语言的新手,在编译了一个 运行 并且可以运行的程序后,我收到了一些编译器警告。

警告说:

main.c: In function ‘lsh_read_line’:
main.c:65:2: warning: pointer targets in passing argument 2 of ‘getline’ differ in signedness [-Wpointer-sign]
    getline(&line, &bufsize, stdin);
    ^
char *lsh_read_line(void)
{
    char *line = NULL;
    ssize_t bufsize = 0;
    getline(&line, &bufsize, stdin);
    return line;
}

我看到的大多数解决方案都建议在分配缓冲区时使用指针 space,但我只是让 getline 自己分配内存,所以我不确定如何更正此问题。

另外,我认为这个警告是相关的,但我不知道它是什么意思或如何更正它:

In file included from main.c:4:0:
/usr/include/stdio.h:678:20: note: expected ‘size_t * __restrict__’ but argument is of type ‘ssize_t *’
 extern _IO_ssize_t getline (char **__restrict __lineptr,
                    ^

错误说它期待 size_t* 而不是 ssize_t*

尝试将 ssize_t bufsize = 0; 更改为 size_t bufsize = 0;

ssize_tsize_t 是不同的类型。 size_t是无符号整数类型,即sizeof的return类型和*allocfread/fwrite等函数的参数类型; size_t 在 C 标准中定义。

另一方面,

ssize_tsigned 整数类型。它不是 C 标准的一部分,但在 POSIX 中用作 return 类型的函数 return 例如字节数 written/read,或错误时的负值.

您不应将这两种类型相互混淆。注意 getline returns ssize_t 但需要一个指向 size_t:

的指针
ssize_t getline(char **lineptr, size_t *n, FILE *stream);

getline returns 读取的字符数,但 *n 将包含分配给缓冲区的字节数。 return 值的类型为 ssize_t - 有符号整数 - 因此在错误 -1 时可以 returned。另一方面,size_t*alloc 函数的参数类型;并且声明说 *n 应该指向内存分配的现有大小 *lineptr 如果 *lineptr 是非空的。

因此

char *lsh_read_line(void)
{
    char *line = NULL;
    size_t bufsize;
    ssize_t n_read = getline(&line, &bufsize, stdin);
    if (n_read < 0) {
        // handle error condition?
        // then maybe:
        return NULL;
    }
    return line;
}

虽然有些人声称它们是 "just" 警告,但关于 C 编译器警告的真相通常是它们在某些情况下可能是严重错误,并导致您的程序具有未定义的行为