我将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_FILEmpfr.h”之前”现在已经过时,AFAIK)。GMP可能会报告一个bug,因此它也可以用Cygwin检测mpfr.h定义。
注意:以上警告来自编译器本身;不涉及链接问题。

关于c - Cygwin的mpfr库发出的gcc编译器警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49880944/

10-12 19:01