Hi all

I am the pgRouting extension main developer, and I came with an interesting 
problem.

We use boost::graph intensively on the C++ code
Currently, getting the data from the data base is done on the C code

I am working on moving code that reads data from postgres: code on a C function 
to a C++ function

This implies that postgres.h​ and several postgres server files need to be 
wrapped with extern

So a header file that has a function that will be linked as C will have the 
following code:

#ifdef __cplusplus
extern "C" {
#endif
#include <postgres.h>
#include <executor/spi.h>
...
}
#endif


But on port.h
https://doxygen.postgresql.org/port_8h_source.html

There are the following definitions

 #define vsnprintf pg_vsnprintf
 #define snprintf pg_snprintf
 #define vsprintf pg_vsprintf
 #define sprintf pg_sprintf
 #define vfprintf pg_vfprintf
 #define fprintf pg_fprintf
 #define vprintf pg_vprintf

And for example:
std::sprintf and std::snprintf are defined on C++ cstdio:​
https://en.cppreference.com/w/cpp/header/cstdio
which pgROuting directly does not includes it but boost::graph does.

Because of that this kind of errors are appearing:

In file included from 
/Users/runner/work/pgrouting/pgrouting/src/dominator/lengauerTarjanDominatorTree_driver.cpp:45:
In file included from 
/Users/runner/work/pgrouting/pgrouting/include/cpp_common/basePath_SSEC.hpp:42:
In file included from /usr/local/include/boost/graph/adjacency_list.hpp:20:
...
In file included from /usr/local/include/boost/ ...
...
In file included from /usr/local/include/boost/exception/exception.hpp:9:
/usr/local/include/boost/assert/source_location.hpp:97:9: error: no member 
named 'pg_snprintf' in namespace 'std'; did you mean simply 'pg_snprintf'?
BOOST_ASSERT_SNPRINTF( buffer, ":%lu", ln );
[100%] Built target topologicalSort
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/boost/assert/source_location.hpp:81:53: note: expanded from 
macro 'BOOST_ASSERT_SNPRINTF'
[100%] Built target mincut
# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::snprintf(buffer, 
sizeof(buffer)/sizeof(buffer[0]), format, arg)
^~~~~
/usr/local/include/postgresql@14/server/port.h:208:12: note: 'pg_snprintf' 
declared here
extern int pg_snprintf(char *str, size_t count, const char *fmt,...) 
pg_attribute_printf(3, 4);
^

As a solution/workaround to that macro getting expanded into the C++ code, this 
looks to work

#ifdef __cplusplus
extern "C" {
#endif
#include <postgres.h>
#include <executor/spi.h>
...
extern "C" {
}
#endif

// undef what needs to be undefined from postgres define
#ifdef __cplusplus

#ifdef sprintf
#undef sprintf
#endif

#ifdef snprintf
#undef snprintf
#endif

...

#endif

Related message:
https://www.postgresql.org/message-id/flat/AM6PR0702MB37832527E6FADE9229CAF1CAAE0A0%40AM6PR0702MB3783.eurprd07.prod.outlook.com

Reply via email to