K&;R练习1-16 clang-getline的冲突类型

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

我正在使用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[]);

/* 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);