我正在使用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;
}
由于某些原因,我认为Cygwin与gcc有关联gmp和mprf的问题...我正在使用gcc版本7.3.0(GCC)。
注意:在我的main.c中,我最初的包含与在线示例相同:
#include <...>
我之前提到我无法链接到库并尝试了数百种不同的方法来尝试链接它们,这里列出的内容太多了。所以最终我拿了一个libs及其标题的副本,然后将它们直接粘贴到包含main.c的同一文件夹中,这就是为什么你看到我的包含为
#include“......”
而不是原始的在线样本。
请注意,我并不熟悉Unix-POSIX
环境,操作或命令行参数,以便在使用gcc / g ++或clang的Unix环境中编译c / c ++代码。我主要习惯于Visual Studio,windows和cmd以及它的功能,设置和语法。现在我正在学习,因为我从文档,网站,在线教程,文本和&amp;视频等。
这可能是针对不同问题的讨论话题,但我认为这可能与部分回答这个问题有关。
当安装Cygwin然后决定安装gcc / g ++而不是mingw的clang时;应该安装gmp和mpir还是必须手动安装,如果是这样的话:按什么顺序? gmp&amp; mpir需要在gcc之前安装还是可以安装之后?订单是否会影响gcc如何链接这些库?正确的安装顺序和库链接是否会解决此编译器警告?
答案 0 :(得分:1)
此答案解释了MPFR和GMP内部的工作原理以及此警告的可能原因。
首先,mpfr_out_str
中的mpfr.h
原型是:
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_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报告错误,以便它也可以使用Cygwin检测FILE
定义。
注意:上面的警告来自编译器本身;不涉及链接问题。