GMP, C++ and extern "C"

Jeronimo Pellegrini pellegrini at
Mon Nov 20 16:44:51 CET 2006

On Mon, Nov 20, 2006 at 04:23:20PM +0100, Emmanuel Thomé wrote:
> On Mon, Nov 20, 2006 at 03:52:27PM +0100, Niels Möller wrote:
> > The most time consuming part that change is not the editing of the
> > header files, but the introduction of a C++ test case, and the
> > corresponding changes to Makefiles and configure script to compile and
> > use the test case only if a C++ compiler is available, and sort out
> > which compiler is to be used for which files.
> ?
> I don't see why you would have to to that. The 
> 	#ifdef	__cplusplus
> 	extern "C" {
> 	#endif
> 	...stuff
> 	#ifdef  __cplusplus
> 	}
> 	#endif
> works inconditionally, and allows your header to be used properly from
> within a C++ program.

The file in question was Nettle's rsa.h, which includes gmp.h.

The problem is that I'd already do:

extern "C" {
#include <nettle/rsa.h>

But then when rsa.h included gmp.h it broke:

/usr/include/gmp.h:2129: error: declaration of C function 'std::ostream& operator<<(std::ostream&, const __mpq_struct*)' conflicts with
/usr/include/gmp.h:2128: error: previous declaration 'std::ostream& operator<<(std::ostream&, const __mpz_struct*)' here
(more errors)

Because when __cplusplus is defined, gmp.h includes this:

__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpz_srcptr);
__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpq_srcptr);
__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpf_srcptr);
__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpz_ptr);
__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpq_ptr);
__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpf_ptr);

which doesn't seem to work inside a block declared extern "C".

I fond that including gmpxx.h *before* gmp.h works:

#include <gmpxx.h>

extern "C" {
#include <rsa.h>  // which includes gmp.h

This way, gmpxx.h will include gmp.h without the C linkage declaration!

However, we can't conditionally include gmpxx.h in rsa.h, because rsa.h
would usually already be inside a 'extern "C"' block...

What is the recommended way of making a C header that uses GMP, and
which can also be used in C++ programs?


More information about the gmp-bugs mailing list