【问题标题】:Cygwin's gcc compiler warning from mpfr library来自 mpfr 库的 Cygwin 的 gcc 编译器警告
【发布时间】:2018-04-17 14:36:16
【问题描述】:

我正在使用带有 gcc 的 Cygwin,我正在尝试运行一个使用 mpfr 库的快速示例程序,并且我有这行代码:

mpfr_out_str (stdout, 10, 0, s, MPFR_RNDD);

我收到了这个编译器警告。

main.c: In function ‘main’:
main.c:21:5: warning: implicit declaration of function ‘mpfr_out_str’; did you mean ‘mpf_out_str’? [-Wimplicit-function-declaration]
     mpfr_out_str (stdout, 10, 0, s, MPFR_RNDD);
     ^~~~~~~~~~~~
     mpf_out_str

然而,当我在网上查看各种网站以获取简单的使用示例时,甚至查看了他们都在使用的 mpfr 文档

mpfr_out_str(...)

...

那么为什么编译器向我抱怨我应该使用

mpf_out_str

相反?


--- main.c --- online example

#include <stdio.h>
#include "gmp.h"
#include "mpfr.h"

int main() {
    unsigned int i;
    mpfr_t s, t, u;

    mpfr_init2 (t, 200);
    mpfr_set_d (t, 1.0, MPFR_RNDD);
    mpfr_init2 (s, 200);
    mpfr_set_d (s, 1.0, MPFR_RNDD);
    mpfr_init2 (u, 200);
    for ( i = 1; i <= 100; i++ ) {
        mpfr_mul_ui (t, t, i, MPFR_RNDU);
        mpfr_set_d (u, 1.0, MPFR_RNDD);
        mpfr_div (u, u, t, MPFR_RNDD);
        mpfr_add (s, s, t, MPFR_RNDD);
    }
    printf( "Sum is " );
    mpfr_out_str (stdout, 10, 0, s, MPFR_RNDD); // this line here
    putchar ('\n');
    mpfr_clear(s);
    mpfr_clear(t);
    mpfr_clear(u);

    return 0;
}

另外出于某种原因,我认为带有 gcc 的 Cygwin 在链接 gmp 和 mprf 时遇到问题...我使用的是 gcc 版本 7.3.0 (GCC)。

注意:在我的 main.c 中,我最初的包含与在线示例相同:

#include <...>

我之前提到我在链接库时遇到了问题,并尝试了数百种不同的方法来尝试链接它们,这里无法列出。因此,最终我复制了库及其标头,并将它们直接粘贴到包含 main.c 的同一文件夹中,这就是为什么您将我的包含视为

#include "..."

而不是原始的在线示例。


请注意,对于在使用 gcc/g++ 或 clang 的 Unix 环境中编译 c/c++ 代码的 Unix-POSIX 环境、操作或命令行参数,我并不十分熟悉。我主要习惯于 Visual Studio、windows 和 cmd 以及它的功能、设置和语法。现在我正在从文档、网站、在线教程(包括文本和视频等)中学习。


这可能是另一个问题的讨论主题,但我认为它可能与部分回答此发布的问题有关。

当一个人安装 Cygwin 然后决定安装 gcc/g++ 而不是 mingw 的 clang;应该已经安装了 gmp 和 mpir 还是必须手动安装它们?如果是:按什么顺序? gmp & mpir 需要在 gcc 之前安装还是可以在之后安装?该命令对 gcc 如何能够链接到此类库有影响吗?正确的安装顺序和库链接能否解决此编译器警告?

【问题讨论】:

  • 你加入了#include &lt;mpfr.h&gt; 吗?
  • 你是#include &lt;gmp.h&gt;#include &lt;mpfr.h&gt; 吗?
  • 测试这个示例代码:mpfr.org/sample.html
  • 如果缺少包含,那么它是重复的。
  • OP 没有反应,所以这可能是问题所在。我要关闭这个。如果是其他问题,请随时联系我。

标签: c gcc cygwin gcc-warning mpfr


【解决方案1】:

此答案解释了 MPFR 和 GMP 内部的工作原理以及此警告的可能原因。

首先,mpfr.h 中的mpfr_out_str 原型是:

size_t mpfr_out_str (FILE*, int, size_t, mpfr_srcptr, mpfr_rnd_t);

注意它使用FILE 类型,它不一定被定义,所以这个原型不能像在GMP 中那样无条件地声明。 MPFR 在以下条件下声明此原型:

#if defined (_GMP_H_HAVE_FILE) || defined (MPFR_USE_FILE)

_GMP_H_HAVE_FILE 来自 GMP 内部,应在 gmp.h 检测到已定义 FILE 时定义。但请注意,这只是一种启发式方法,因为 C 标准没有指定进行此类检测的方法,这可能是警告的原因(见下文); gmp.h 目前有:

#if defined (FILE)                                              \
  || defined (H_STDIO)                                          \
  || defined (_H_STDIO)               /* AIX */                 \
  || defined (_STDIO_H)               /* glibc, Sun, SCO */     \
  || defined (_STDIO_H_)              /* BSD, OSF */            \
  || defined (__STDIO_H)              /* Borland */             \
  || defined (__STDIO_H__)            /* IRIX */                \
  || defined (_STDIO_INCLUDED)        /* HPUX */                \
  || defined (__dj_include_stdio_h_)  /* DJGPP */               \
  || defined (_FILE_DEFINED)          /* Microsoft */           \
  || defined (__STDIO__)              /* Apple MPW MrC */       \
  || defined (_MSL_STDIO_H)           /* Metrowerks */          \
  || defined (_STDIO_H_INCLUDED)      /* QNX4 */                \
  || defined (_ISO_STDIO_ISO_H)       /* Sun C++ */             \
  || defined (__STDIO_LOADED)         /* VMS */                 \
  || defined (__DEFINED_FILE)         /* musl */
#define _GMP_H_HAVE_FILE 1
#endif

或者,用户可以在包含mpfr.h 之前定义MPFR_USE_FILE(这通常不是必需的,因为自动检测应该可以工作)。

现在,OP 收到的警告信息是:

main.c: In function ‘main’:
main.c:21:5: warning: implicit declaration of function ‘mpfr_out_str’; did you mean ‘mpf_out_str’? [-Wimplicit-function-declaration]
     mpfr_out_str (stdout, 10, 0, s, MPFR_RNDD);
     ^~~~~~~~~~~~
     mpf_out_str

EDIT当我使用不正确的代码时,我也会收到此警告:

#include "gmp.h"
#include "mpfr.h"
#include <stdio.h>

&lt;stdio.h&gt; 不包括在之前 mpfr.h)。我不知道为什么 gcc 建议 mpf_out_str 代替:可以使用 gcc -E 检查它也没有被声明!事实上,gmp.h 有:

#define mpf_out_str __gmpf_out_str
#ifdef _GMP_H_HAVE_FILE
__GMP_DECLSPEC size_t mpf_out_str (FILE *, int, size_t, mpf_srcptr);
#endif

_GMP_H_HAVE_FILE 未定义。

所以,GMP 也会有同样的问题。我建议在包含mpfr.h 之前定义MPFR_USE_FILE,如上所述并如MPFR 手册中所述(注意:约束“在第一次包含mpfr.hgmp.h 之前”现在已过时,AFAIK)。可以针对 GMP 报告一个错误,以便它也可以使用 Cygwin 检测到 FILE 定义。

注意:以上警告来自编译器本身;不涉及链接问题。

【讨论】:

  • 快速谷歌搜索似乎表明 cygwin 使用列表中的 _STDIO_H。
  • 多么令人愉快和出色的答案。用简单的英语很容易理解和理解。通过展示如何以其他方式生成相同警告的示例,指出了罪魁祸首。非常好的答案。我现在给你投了赞成票。我得再深入一点;手册和文档有点难读……主要是因为他们假设您了解 Unix 环境 Posix,而我目前的困难在于。我对 C 代码有点了解,但自从我使用 C 以来已经有好几年了,在过去的几十年里,我一直在使用 Visual C++。
  • 现在,奇怪的建议是直接来自 gcc 编译器,或者它可能与 Cygwin 的内部有关...,或两者兼而有之?
  • 其实这个建议并不奇怪(至少来自gcc的POV),宏mpf_out_str是定义的,即使函数没有声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
相关资源
最近更新 更多