【问题标题】:Mingw -- Conflicting types for function due to previous declarationMingw——由于先前的声明,函数的类型冲突
【发布时间】:2020-10-11 14:35:39
【问题描述】:

首先,当我在远程连接的 Linux 机器上编译/“制作”代码时,我没有遇到这个问题。我只在安装了 Mingw 的 Windows 笔记本电脑上遇到过这种情况——我认为这是导致问题的原因。

$ make
gcc -c parser.c
parser.c:34:7: error: conflicting types for 'gets'
   34 | char* gets(char *buf, int max)
      |       ^~~~
In file included from parser.h:4,
                 from parser.c:1:
c:\mingw\include\stdio.h:709:41: note: previous declaration of 'gets' was here
  709 | _CRTIMP __cdecl __MINGW_NOTHROW  char * gets (char *);
      |                                         ^~~~
Makefile:13: recipe for target 'parser.o' failed
make: *** [parser.o] Error 1

这是所要求的gets()代码:

char* gets(char *buf, int max)
{
  int i, cc;
  char c;

  for(i=0; i+1 < max; ){
    cc = read(0, &c, 1);
    if(cc < 1) break;
    //c = getchar();
    buf[i++] = c;
    
    if(c == '\n' || c == '\r') 
        break;
  }
  
  buf[i] = '\0';
  return buf;
}

有没有办法在不改变gets函数名的情况下解决这个问题?谢谢sm

【问题讨论】:

  • @anastaciu 我不是。我认为代码中没有问题,因为我在 Linux 机器上运行它没有问题。
  • gets 函数已正式C 标准中删除(但一些编译器仍将其包含在标准库的实现中) .在 C++ 中,它在 C++11 标准和 removed in C++14 中被弃用。您是否可能在两个平台上使用不同的标准? (也就是说,请确保您使用的是 C++14 或更高版本。)
  • 另外,您能否澄清一下您使用的是 C++ 还是 C。gcc -c parser.c 行在我看来就像您在 C 源代码上调用 C 编译器。也许你想要g++ -c parser.cpp -std=c++14 ??
  • @alee,这不太可能是问题,因为在 gcc 中 gets 在没有 std 命名空间的情况下可用,但这可能是一些疯狂的冲突,无论如何,这很奇怪你的 get 有 2 个参数,它不应该与库 gets 冲突,尽管它已从 C 和 C++ 标准中删除,但由于某种原因尚未从 gcc 中删除。
  • 自从我使用 MingW 或任何 GNU 主线东西以来已经有很长时间了,但是 gcc 是 IIRC,仅用于 C 并且正如 @anastaciu 所说(和我暗示过),对于 C++,您需要 g++

标签: c mingw


【解决方案1】:

您的代码可以在 Linux 的 gcc 上运行,因为 the gets function was removed 理应如此,因为它在 C99 标准中已被弃用并被 C11 删除。

由于某种原因,Windows MingW 发行版仍然维护gets,因此您遇到了重新定义问题。

很遗憾,您不能使用该函数名,除非您从 stdio.h 中手动删除它,因为 C 不允许函数重载。

Running sample on Linux gcc

Running sample on Windows gcc

【讨论】:

  • 是的:\。我最终完全删除了 Mingw 并安装了 Cygwin。
  • @alee,好动作,不过重命名函数会更容易。
  • 我认为要补充的重要一点是,由于这是 C 而不是 C++,因此不可能重载该函数,因为 OP 没有重新定义 gets(char*)
  • @AlexShirley,你说得对,我添加了一个注释,我不会提及 C++,因为这是一个关于 C 的问题,这里的人不会那么友好 ;)。
  • @alee 是的,如果您无法更改代码,那可能是正确的选择。不过,我会在新项目中避免使用它,它的主要目的是在 Windows 上以不可移植的方式(大量使用 POSIX)运行最初为 Linux 编写的代码。
【解决方案2】:

正如错误所说,gets() 函数已在 stdio.h 中定义。

你可以做的一个技巧是这样写:

#define gets MY_gets

在您定义 gets() 函数之前。

这样您实际上是在定义一个不会导致冲突的MY_gets() 函数。当您稍后在代码中调用 gets() 时,您实际上是在调用 MY_gets()

如果您在头文件中定义gets(),则应首先包含stdio.h,然后将#define gets MY_gets放在头文件中gets()的声明之前。

虽然我不明白如果它已经存在,你为什么要改进这个功能。 仅在需要时定义它并用 #ifndef HAVE_GETSendif 之类的东西包围函数更有意义,其中 HAVE_GETS 应根据配置/构建系统中完成的测试来定义。

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    相关资源
    最近更新 更多