Undefined reference to __ms_vsnprintf.

Georg-Johann Lay avr at gjlay.de
Mon Feb 24 10:14:43 UTC 2020

Hi, I am running into an undefined reference when I am using gmp_printf 
like in the following test case:

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

int main()
     mpz_t z;
     mpz_init_set_si (z, 123);

     gmp_printf ("z = %Zd\n", z);

     mpz_clear (z);
     return 0;

Linking under Windos:

.../lib/libgmp.a(doprntf.o):doprntf.c:(.text+0x24): undefined reference 
to `__ms_vsnprintf'

Adding -Wl,-v to the compilation:

...ld.exe ... -lgmp -v -lmingw32 -lgcc -lm
oldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 
-lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt

So all stuff appears to be present, in particular libmingwex.a.

Any hints what's going wrong here?

stdio.h reads:

  * Formatted Output
  * MSVCRT implementations are not ANSI C99 conformant...
  * we offer these conforming alternatives from libmingwex.a
#undef  __mingw_stdio_redirect__
#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __mingw_##F

extern int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...);
extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const 
char*, __VALIST);

Consequently, I can work around the problem by linking with:


and it appears to work as expected.

So is this a glitch in GMP build machinery?

I configured and built that libgmp.a on linux with:

$ ../../source/gmp-6.1.2/configure --host=i686-w64-mingw32 --prefix=... 
--with-gnu-ld --enable-cxx --enable-static --disable-shared

That i686-w64-mingw32 toolchain's stdio.h also defines __mingw_vsnprintf:

extern __attribute__((__format__ (gnu_printf, 3, 0))) 
int __cdecl __mingw_vsnprintf(char * __restrict__ _DstBuf,size_t 
_MaxCount,const char * __restrict__ _Format, va_list _ArgList);

however it depends on macro __USE_MINGW_ANSI_STDIO (and maybe also 
_GNU_SOURCE, I am a bit lost in them nested macros):

  * User has expressed a preference for C99 conformance...
__attribute__((__format__ (gnu_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
int snprintf (char *__stream, size_t __n, const char *__format, ...)
   register int __retval;
   __builtin_va_list __local_argv; __builtin_va_start( __local_argv, 
__format );
   __retval = __mingw_vsnprintf( __stream, __n, __format, __local_argv );
   __builtin_va_end( __local_argv );
   return __retval;

#if !defined (__USE_MINGW_ANSI_STDIO) || __USE_MINGW_ANSI_STDIO == 0
/* this is here to deal with software defining
  * vsnprintf as _vsnprintf, eg. libxml2.  */
#pragma push_macro("snprintf")
#pragma push_macro("vsnprintf")
# undef snprintf
# undef vsnprintf
   int __cdecl __ms_vsnprintf(char * __restrict__ d,size_t n,const char 
* __restrict__ format,va_list arg)

   int vsnprintf (char * __restrict__ __stream, size_t __n, const char * 
__restrict__ __format, va_list __local_argv)
     return __ms_vsnprintf (__stream, __n, __format, __local_argv);

Is this a glitch in GMP's configure and __USE_MINGW_ANSI_STDIO should be 
set?  Or can / should I do that by hand and where?

I am using that i686-w64-mingw32 toolchain successfully to build much 
larger projects for Windos / MinGW like GCC, so it appears to work 
reasonably well.

Thanks for your support,


More information about the gmp-discuss mailing list