我编写了这个微不足道的小程序来演示我的问题(标题为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 标志无济于事。
那么,我做错了什么?我怎样才能编译这个?我难住了。
您已设置-std=c11 -Wpedantic,这意味着除非您显式设置_POSIX_C_SOURCE或之一,否则正常定义不可用并且不会声明 POSIX 函数_XOPEN_SOURCE。#define _XOPEN_SOURCE 700在第一个之前添加(甚至在 Linux 上添加800 个)#include,一切都会好起来的。
你CPPFLAGS = -D_XOPEN_SOURCE=700在makefile; 做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被认可的通用标准。