ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
c_cpp_compatibility.h
Go to the documentation of this file.
1/**
2 * @file c_cpp_compatibility.h
3 * @brief Fix macro conflicts between PostgreSQL headers and the C++ STL/Boost.
4 *
5 * Two families of PostgreSQL macros break C++ headers included after them:
6 *
7 * - When PostgreSQL is built without @c --enable-nls, its headers redefine
8 * @c gettext, @c ngettext, @c dgettext, and @c dngettext as no-op macros.
9 * Several STL and Boost headers later include @c <libintl.h>, which tries
10 * to declare the real function prototypes for those same names. The
11 * resulting macro/declaration clash causes compilation errors.
12 *
13 * - @c port.h replaces the printf family (@c snprintf, @c sprintf…) with
14 * @c pg_* macros for output consistency. Any later-included C++ header
15 * that calls the @c std::-qualified functions then breaks -- e.g.
16 * @c boost/assert/source_location.hpp (Boost >= 1.79) calls
17 * @c std::snprintf, which the macro turns into the non-existent
18 * @c std::pg_snprintf.
19 *
20 * This header must be included in every translation unit that mixes
21 * PostgreSQL C headers with C++ STL or Boost headers, *after* the
22 * PostgreSQL headers. It undefines the offending macros so subsequent
23 * STL/Boost headers parse cleanly. C++ code does not rely on
24 * @c pg_snprintf semantics (such as @c %m), so losing the replacement is
25 * harmless. @c provsql_utils.h includes it automatically when compiled
26 * as C++, so most translation units are covered transitively.
27 *
28 * Deliberately *no* include guard: undefining is idempotent, and a guard
29 * would make a second inclusion a no-op -- leaving the macros defined when
30 * the first inclusion happened before the PostgreSQL headers.
31 *
32 * The cleanest long-term fix for the gettext clash is to build PostgreSQL
33 * with @c --enable-nls, but that is not always under the extension
34 * author's control.
35 */
36
37/* When compiling PostgreSQL without --enable-nls, gettext, ngettext,
38 * dgetttext, dngettext are replaced with macros; but some STL headers (in
39 * particular used by Boost) use the definitions of these functions from
40 * libintl.h; to avoid conflicts between these declarations, for files
41 * that include both C PostgreSQL headers and STL headers, we need to
42 * undefine the macros. It is usually better to compile PostgreSQL with
43 * --enable-nls, though, but we do not have control over this. */
44
45#undef gettext
46#undef ngettext
47#undef dgettext
48#undef dngettext
49
50/* port.h's printf-family replacements (see file comment). */
51
52#undef snprintf
53#undef vsnprintf
54#undef sprintf
55#undef vsprintf
56#undef fprintf
57#undef vfprintf
58#undef printf
59#undef vprintf