Clang 无法编译 c11 程序,理由是“隐式声明在 c99 中是非法的”

sco*_*ame 5 c posix clang

我编写了这个微不足道的小程序来演示我的问题(标题为hello.c)(旁注:我注意到此程序中存在内存泄漏,但这只是一个示例,因此并不重要):

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv) {
    char * buf = NULL;
    size_t buflen = 0;

    ssize_t line_len;

    while ((line_len = getline(&buf, &buflen, stdin)) > 0) {
        buf[line_len - 1] = '\0';

        char * val = getenv(buf);

        if (val) {
            printf("setenv %s \"%s\"\n", buf, val);
        }
        else {
            fprintf(stderr, "warning: %s not found\n", buf);
        }
    }

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

这在 Linux 下编译得很好,使用带有以下 makefile 的 gcc 和 gnu make:

CFLAGS += -std=c11 -Wall -Werror -Wpedantic
CPPFLAGS := -D_XOPEN_SOURCE=700

EXES := hello

all: $(EXES)

clean:
    rm -f $(EXES) *.o
Run Code Online (Sandbox Code Playgroud)

但是,在 BSD 下,使用 clang 和 bmake,我无法编译(使用完全相同的 makefile 和源文件),因为它说

hello.c:11:24: error: implicit declaration of function 'getline' is invalid in
  C99 [-Werror,-Wimplicit-function-declaration]
Run Code Online (Sandbox Code Playgroud)

问题是,正如您所看到的,我不是在 c99 模式下编译,而是在 c11 模式下编译,而且,根据手册页定义_POSIX_C_SOURCE为 200809 或更高版本应该启用 getline,而在其他地方我确信定义_XOPEN_SOURCE为 700应该达到那个。

取出 -W 标志无济于事。

那么,我做错了什么?我怎样才能编译这个?我难住了。

Jon*_*ler 5

您已设置-std=c11 -Wpedantic,这意味着除非您显式设置_POSIX_C_SOURCE或之一,否则正常定义不可用并且不会声明 POSIX 函数_XOPEN_SOURCE#define _XOPEN_SOURCE 700在第一个之前添加(甚至在 Linux 上添加800 个)#include,一切都会好起来的。

CPPFLAGS = -D_XOPEN_SOURCE=700makefile; 做CPPFLAGS显示在 GCC 命令行上?

我经常在 Mac OS X 10.10.1 上编译,-std=c11并且我有一个设置_XOPEN_SOURCE为 700的标头。但是,我可以使用您的代码并逐字编译:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Werror -pedantic -c yourprog.c
Run Code Online (Sandbox Code Playgroud)

唯一的抱怨是既不使用argc也不argv使用(因此编译确实失败,但不是因为getline())。

注意CPPFLAGSBSD 不一定认可make。没有一个需要CPPFLAGS被认可的通用标准。