K&;R练习1-16 clang-getline的冲突类型
我正在使用K&R,使用Clang作为我的编译器 练习1-16在使用Clang编译时产生“getline的冲突类型”错误。我猜是因为其中一个默认库有一个getline函数 在编写K&R练习时,我应该向Clang传递哪些选项,以避免包含任何其他内容 要修改的练习示例为:K&;R练习1-16 clang-getline的冲突类型,c,clang,C,Clang,我正在使用K&R,使用Clang作为我的编译器 练习1-16在使用Clang编译时产生“getline的冲突类型”错误。我猜是因为其中一个默认库有一个getline函数 在编写K&R练习时,我应该向Clang传递哪些选项,以避免包含任何其他内容 要修改的练习示例为: #include <stdio.h> #define MAXLINE 1000 int getline(char line[], int maxline); void copy(char to[], char from
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print longest input line */
main()
{
int len; /* current line length */
int max; /* maximum line lenght seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if ( len > max) {
max = len;
copy(longest, line); /* line -> longest */
}
if (max > 0) /* there was a line */
printf("\n\nLength: %d\nString: %s", max -1, longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
int c,i;
for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* copy: copy "from" into "to"; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while((to[i] = from[i]) != '\0')
++i;
}
这里有一个类似的问题: 这是相同的问题,但与海湾合作委员会。一种解决方案是将编译器置于ANSIC模式,这将禁用GNU/POSIX扩展 请尝试以下操作:
$ clang test.c -ansi
或者
$ clang test.c -std=c89
在我的机器上成功测试:
$ clang --version
clang version 3.3 (tags/RELEASE_33/rc2)
Target: x86_64-redhat-linux-gnu
Thread model: posix
在我大学的机器上使用此编译器,甚至无需指定ANSI模式即可成功编译:
->clang --version
Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
Target: x86_64-apple-darwin10
Thread model: posix
问题在于您的系统已经提供了一个名为
getline
的函数mangetline
应该告诉你它的签名。在我的系统上,它是:
ssize_t getline(char ** restrict linep, size_t * restrict linecapp, FILE * restrict stream);
您可以匹配它,也可以将函数重命名为“mygetline”或类似的名称
或者,如果可以避免包含stdio.h
,则可以完全避免该问题
关于你的最后一个问题:
在编写K&R练习时,我应该向Clang传递哪些选项,以避免包含任何其他内容
你不能-系统标题就是它们,并且自1988年K&R上一次修订以来,大概一直在继续。从那时起,已经有多个C标准更新。在某些方面,K&R真的开始变得麻烦了。对于手边没有K&R副本的人,你能发布一个示例程序以及你在编译它时遇到的错误吗?这不起作用,系统定义仍然会与OP冲突。我仍然会用-ansi选项得到错误。我只需要重命名这个函数。我的经验与@retrodev匹配-
-ansi
标志没有改变任何东西:$cc-ansi-c-o example.o example.c
给出的输出:示例。c:3:5:错误:“getline”的类型冲突。
必须是Linux和Mac OS X上的头差异。快速查看linux手册页可以发现,glibc
有宏要测试它的存在,这就是为什么-ansi
和-std=c89
对您有效的原因。MacOSX没有这样的防护。我的linux机器上的glibc特性测试,供参考:\u POSIX\u C\u SOURCE>=200809L | | | XOPEN\u SOURCE>=700
@CarlNorum:这太奇怪了。ANSI或ISO C标准的任何版本都没有定义名为getline
的函数,这意味着一致性编译器必须允许在用户代码中使用该名称。如果cc-ansi
或cc-std=c89
(或c90
,或c99
,或c11
)仍然给您带来冲突,那么cc
(或cc
调用的任何内容)中有一个bug。在我的Linux系统上,它可以与gcc
和clang
一起正常工作。我没想到是在stdio.h。我使用Unix已经有一段时间了,但我正在学习C语言,这样我就可以通过这种方式更加熟悉它。谢谢大家!@retrodev-错误消息明确表示前面的定义在stdio.h
中:“/usr/include/stdio.h:449:9:注意:前面的声明在这里
”getline
由POSIX定义,但不是ANSI或ISO C。只要以某种符合标准的模式调用编译器,就应该能够在自己的代码中使用该名称。在我的系统上,
中的getline
声明受#ifdef
s保护。尽管我认为应该避免使用与POSIX标准函数冲突的名称。
ssize_t getline(char ** restrict linep, size_t * restrict linecapp, FILE * restrict stream);