1

I'm using Cygwin with gcc and I'm trying to run a quick sample program that uses mpfr library and I have this line of code:

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

And I'm getting this compiler warning.

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

Yet when I looked online at various sites for simple examples of use and even looked though the mpfr docs they were all using

mpfr_out_str(...)

...

So why is the compiler complaining to me that I should be using

mpf_out_str

Instead?


--- 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;
}

Also for some reason I think Cygwin with gcc is having issues linking against gmp and mprf... I'm using gcc version 7.3.0 (GCC).

Note: In my main.c I originally had the includes the same as the online example:

#include <...>

I previously mentioned that I had trouble linking against the library and tried hundreds of different ways to try and link against them, too many to list here. So eventually I took a copy of the libs and their headers and just pasted them directly into the same folder that contains main.c and this is why you see my includes as

#include "..."

instead of the original online sample.


Mind you I'm not all that familiar with Unix-POSIX environment, operations or command line arguments for compiling c/c++ code on a Unix environment that uses either gcc/g++ or clang. I've primarily been accustomed to Visual Studio, windows and cmd and it's features, settings and syntax. Right now I'm learning as I go from documentation, websites, online tutorials both text & video, etc.


This may be a topic of discussion for a different question, but I think that it might relate into partially answering this posted question.

When one installs Cygwin and then decides to install gcc/g++ as opposed to mingw's clang; should gmp and mpir already be installed or do they have to be installed manually and if so: in what order? Does gmp & mpir need to be installed before gcc or can it be installed after? Does the order make a difference in how gcc is able to link against such libraries? Would the proper installation order and linking of libraries resolve this compiler warning?

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59

1 Answers1

1

This answer explains how things work in MPFR and GMP internals and the possible cause of this warning.

First, the mpfr_out_str prototype in mpfr.h is:

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

Note that it uses the FILE type, which is not necessarily defined, so that this prototype must not be declared unconditionally, like in GMP. MPFR declares this prototype under the condition:

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

_GMP_H_HAVE_FILE comes from GMP internals and should be defined when gmp.h has detected that FILE is defined. But note that this is only a heuristic since the C standard does not specify a way to do such detection, and this may be the cause of the warning (see below); gmp.h currently has:

#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

Alternatively, the user can define MPFR_USE_FILE before including mpfr.h (this should normally not be necessary as auto-detection should work).

Now, the warning message the OP gets is:

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 I also get this warning when I use the incorrect code:

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

(<stdio.h> not being included before mpfr.h). I don't know why gcc suggests mpf_out_str instead: one can check with gcc -E that it has not been declared either! And indeed, gmp.h has:

#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

while _GMP_H_HAVE_FILE is not defined.

So, there would be the same issue with GMP. I suggest to define MPFR_USE_FILE before including mpfr.h as said above and as documented in the MPFR manual (note: the constraint "before the first inclusion of mpfr.h or gmp.h" is now obsolete, AFAIK). A bug could be reported against GMP so that it detects the FILE definition with Cygwin too.

Note: the above warning is from the compiler itself; linking issues are not involved.

vinc17
  • 2,829
  • 17
  • 23
  • A quick google search seems to indicate cygwin uses _STDIO_H, which is in the list. – Marc Glisse Apr 18 '18 at 10:43
  • What a delightful and excellent answer. Very easy to follow and understand in plain words English. Pointed out what could be the culprit by showing examples of how the same warning can be generated in other ways. Very nice answer. I gave you an up vote for now. I'll have to dig into a little more; the manuals and docs are a bit of a tough read... mainly because they assume you know Unix environments Posix, and there lies my difficulties for the time being. I understand C code a little bit, buts its been years since I've worked with C, for the past few decades I've been working in Visual C++. – Francis Cugler Apr 18 '18 at 10:51
  • Now, for the weird suggestion is that coming from the gcc compiler directly, or could it have something to do with the internals of Cygwin..., or a combination of both? – Francis Cugler Apr 18 '18 at 10:53
  • Actually the suggestion is not weird (at least from gcc's POV), the macro mpf_out_str is defined even if the function is not declared. – Marc Glisse Apr 18 '18 at 10:57