我将 Cygwin 与 gcc 一起使用,我正在尝试运行一个使用 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 <...>
我之前提到过我在链接到库时遇到了问题,并尝试了数百种不同的方法来尝试链接到它们,这里无法一一列举。所以最终我复制了这些库及其 header ,并将它们直接粘贴到包含 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 如何链接此类库?正确的安装顺序和库链接是否可以解决此编译器警告?
最佳答案
此答案解释了 MPFR 和 GMP 内部的工作原理以及此警告的可能原因。
首先,mpfr_out_str
原型(prototype)在 mpfr.h
是:
size_t mpfr_out_str (FILE*, int, size_t, mpfr_srcptr, mpfr_rnd_t);
请注意,它使用了 FILE
type,它不一定被定义,所以这个原型(prototype)不能无条件地声明,就像在 GMP 中一样。 MPFR 在以下条件下声明此原型(prototype):
#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_USE_FILE
在包括 mpfr.h
之前(这通常不是必需的,因为自动检测应该可以工作)。
现在,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
编辑 当我使用不正确的代码时,我也会收到此警告:
#include "gmp.h"
#include "mpfr.h"
#include <stdio.h>
(<stdio.h>
未包含在 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_USE_FILE
在包括 mpfr.h
之前如上所述和 MPFR 手册中所述(注意:约束“在第一次包含 mpfr.h
或 gmp.h
之前”现在已过时,AFAIK)。可以针对 GMP 报告错误,以便它检测到 FILE
也可以使用 Cygwin 进行定义。
注意:以上警告来自编译器本身;不涉及链接问题。
关于来自 mpfr 库的 Cygwin 的 gcc 编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49880944/