Skip site navigation (1) Skip section navigation (2)

Mostly Harmless: Welcoming our C++ friends

From: Kurt Harriman <harriman(at)acm(dot)org>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Mostly Harmless: Welcoming our C++ friends
Date: 2008-12-05 08:27:25
Message-ID: 4938E5ED.60102@acm.org (view raw or flat)
Thread:
Lists: pgsql-hackers
Hi,

Sometimes people would like to call C++ code in the PostgreSQL
backend environment... for example, in user-defined functions,
triggers, access methods.  And there is sometimes a need for
C++ code to call back into PostgreSQL's C functions, such as
the SPI interface.  Many useful software packages and
libraries are written in C++.

The attached series of 4 patches is meant to provide a minimal
level of support for C++ aficionados to easily compile and link
with the PostgreSQL backend.  No new interfaces or wrappers are
provided.  The goal is merely to make the backend a friendlier
place for developing extensions involving C++, with minimal
impact on the existing C code.

The proposed change is divided into 4 patches with the hope
that each will be simple and easy to review.  They can be
reviewed and discussed independently, and I hope some or
all may be judged benign enough to be taken up into 8.5 or
earlier.

The patches are described in more detail below.  They are:

	1.  c++reserved -- changes a few field and parameter
		names which happened to be C++ reserved words

	2.  c++bookends -- adds C linkage declarations to a
		few header files

	3.  c++configure -- adds C++ support to 'configure',
		'make', and 'pg_config'.  A new configure option
		--enable-cplusplus links the C++ runtime library
		in to the postgres backend.

	4.  c++exception -- converts unhandled C++ exceptions to
		PostgreSQL elog(FATAL) errors

Regards,
... kurt


These patches are based on CVS head in which the latest commit was
  user:        petere
  date:        Thu Dec 04 17:51:28 2008 +0000
  summary:     Default values for function arguments


1. c++reserved

	User-defined functions and extensions may need to access
	backend data structures such as parse trees.  A few of the
	relevant header files contain field or parameter names
	which happen to be C++ reserved words.  This makes them
	unusable from C++ because the compiler chokes on the
	reserved word.  It has been suggested that the C++ user
	could surround these #includes with #defines to substitute
	innocuous words for the reserved words; but that would be
	unbearably kludgy, error prone and unmaintainable.  A polite
	host does not demand such things of a guest.

	Fortunately, there are not many instances which are likely
	to be encountered by our C++ guests, and these can easily
	be changed.  In memnodes.h, parsenodes.h, and primnodes.h,
	this patch changes the following field names:

		typename => typeName
		typeid => typeOid
		using => usingClause
		delete => delete_context
		
	Also, the patch changes a few parameter names in function
	prototypes in makefuncs.h, parse_type.h, and builtins.h:

                 typename => typeName
		typeid => typeOid
		namespace => qualifier

	There's no need to ask PostgreSQL developers to remember to
         avoid C++ reserved words, because C++ users who are affected
	by such occurrences can be asked to submit a corrective patch.

2. c++bookends

	C++ code can call C functions and share global variables with C,
	provided those declarations are surrounded by "bookends":

		extern "C" {
		...
		};

	Header files can be made bilingual, to declare interfaces which
	look the same to both C and C++ callers.  This is done by
	placing C++ bookends within the header file, guarded by #ifdefs

		#ifdef __cplusplus
		extern "C" {
		#endif
		...
		#ifdef __cplusplus
		}; /* extern "C" */
		#endif

	This way the C++ caller can just #include the header file without
	worrying whether the interface is implemented in C or C++.

	Usually, extension modules written in C++ will put bookends around
	all of their PostgreSQL #includes.

	However, "postgres.h" usually stands alone as the first #include,
	followed by some system #includes, and then the rest of the
	PostgreSQL #includes.  It is much nicer if a C++ file has just one
	pair of bookends around its main block of PostgreSQL #includes.
	This patch gives postgres.h its own internal bookends, making it
	bilingual, so that its #include can continue to stand alone at the
	head of each file.

	Just a few additional header files are mentioned in the PostgreSQL
	Reference Manual for add-on developers to use: fmgr.h, funcapi.h,
	and spi.h.  This patch adds bookends within those three files for
	the benefit of beginners writing very simple extensions in C++.
	Documentation and learning are simplified because C example code
	can be compiled as C or C++ without change.

3. c++configure

	This patch adds C++ support to the PostgreSQL build system.

	After you have applied the patch, cd to the top of the source
	tree (to the directory containing the file 'configure.in') and
	execute these two commands to regenerate the 'configure' script
	and some related files:
		autoconf
		autoheader

	Much as it already does for the C compiler, the 'configure' script
	will try to find the C++ compiler and set up appropriate command
	line options.  If 'configure' finds a C++ compiler, it will set up
	src/Makefile.global to define the following makefile variables:

		CXX = command for invoking C++ compiler
		CXXCPP = command for invoking C++ preprocessor
		CXXFLAGS = C++ compiler options
		GXX = 'yes' if the C++ compiler is gcc/g++

	Implicit rules are defined so that gmake will automatically invoke
	the C++ compiler using the above variables given a source file name
	suffixed with '.cpp' or '.cc'.  So, to add a file named marvin.cpp
	to the build, just add 'marvin.o' to the OBJS list in the Makefile.

	To C++-compile a file with '.c' suffix, the Makefile should list
	the .o file in both OBJS and CXXOBJS.

	The pg_config utility can be used to display the CXX and CXXFLAGS.

	Most C++ code typically uses some C++ features whose implementation
	makes use of the compiler's runtime library: exceptions, static
	constructors, new/delete, STL containers, stream I/O, etc.  Specify
	the following 'configure' option to link the C++ runtime library
	into the postgres backend:

		--enable-cplusplus

	If --enable-cplusplus is specified, the makefile variable
	'enable_cplusplus' will be set to 'yes', and pg_config.h will
	#define ENABLE_CPLUSPLUS.

	To ensure that the C++ runtime library is properly initialized,
	on some platforms it is necessary for the main() function to be
	compiled as C++.  Therefore, if --enable-cplusplus is configured,
	src/backend/main/main.c will be compiled as C++.  This is
	handled by the following lines in src/backend/main/Makefile:

		ifeq ($(enable_cplusplus),yes)
		CXXOBJS = main.o
		endif

	Fortunately, main.c can be compiled as either C or C++ with no
	difficulty after applying the c++reserved and c++bookends
	patches.  To make main.c bilingual, all that was needed was
	a pair of bookends around its #includes.

	Limitations:

	- I haven't added support for profiling and code coverage for
	  C++.  Automatic dependency generation is supported, however.

	- This ought to work on platforms which use GCC, and maybe some
	  others.  The only one I have tested is x86_32 Linux with GCC
	  4.1.2.  Hopefully some interested hackers will try it on
	  platforms to which they have access, and post the results.

4. c++exception

	When C code calls C++ code, all C++ exceptions need to be caught
	and fully contained within the C++ code.  Exceptions should never
	be thrown outward across the C/C++ frontier.

	If an exception is not caught within C++ code, and the search for
	a matching 'catch' bumps into a C stack frame, the result may be
	platform dependent.  On my platform (Linux/GCC), if this happens
	in the postgres backend, the process terminates silently as if
	abort() had been called.

	With this patch, if --enable-cplusplus is configured,
	PostgresMain defines a handler to intercept any uncaught C++
	exception and convert it to a conventional PostgreSQL error of
	FATAL severity.  This allows the backend to clean up and report
	the error before terminating.

	



	
	
	


	

	


	


	


Attachment: c++exception.patch
Description: text/plain (3.3 KB)
Attachment: c++configure.patch
Description: text/plain (13.5 KB)
Attachment: c++bookends.patch
Description: text/plain (2.0 KB)
Attachment: c++reserved.patch
Description: text/plain (47.4 KB)

Responses

pgsql-hackers by date

Next:From: Greg SmithDate: 2008-12-05 08:39:48
Subject: Re: contrib/pg_stat_statements 1202
Previous:From: Greg SmithDate: 2008-12-05 08:26:47
Subject: Re: [patch] pg_upgrade script for 8.3->8.4

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group