我将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
相反呢?
---主.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中,最初的includes与在线示例相同:
#include <...>
我之前提到过,我在链接库时遇到了问题,尝试了数百种不同的方法来尝试链接它们,太多了,无法在此列出。所以最终我复制了一份libs和它们的头文件,直接粘贴到包含main.c的同一个文件夹中,这就是为什么你会把我的includes看作
#包括“…”
而不是原始的在线样本。
请注意,我不太熟悉在使用g c c/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
中的原型是:
size_t mpfr_out_str (FILE*, int, size_t, mpfr_srcptr, mpfr_rnd_t);
请注意,它使用了
mpfr.h
类型,不一定要定义该类型,因此不能像GMP中那样无条件地声明该原型。MPFR在以下条件下声明此原型:#if defined (_GMP_H_HAVE_FILE) || defined (MPFR_USE_FILE)
FILE
来自GMP内部,应在_GMP_H_HAVE_FILE
检测到gmp.h
已定义时定义。但请注意,这只是一种试探性的方法,因为C标准没有指定进行这种检测的方法,这可能是警告的原因(见下文);目前有:#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
或者,用户可以在包含
FILE
之前定义gmp.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>
(
MPFR_USE_FILE
不包括在mpfr.h
之前)。我不知道为什么gcc建议<stdio.h>
而不是:可以用mpfr.h
检查它也没有被声明!事实上,mpf_out_str
已经:#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
而
gcc -E
未定义。所以,GMP也会有同样的问题。我建议在包含
gmp.h
之前定义_GMP_H_HAVE_FILE
,如上文所述,并记录在MPFR手册中(注:约束“在第一次包含MPFR_USE_FILE
或mpfr.h
”之前”现在已经过时,AFAIK)。GMP可能会报告一个bug,因此它也可以用Cygwin检测mpfr.h
定义。注意:以上警告来自编译器本身;不涉及链接问题。
关于c - Cygwin的mpfr库发出的gcc编译器警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49880944/