mirror of
https://github.com/postgres/postgres.git
synced 2026-03-23 10:55:21 -04:00
Calling copyObject in C++ without GNU extensions (e.g. when using
-std=c++11 instead of -std=gnu++11) fails with an error like this:
error: use of undeclared identifier 'typeof'; did you mean 'typeid'
This is due to the C compiler used to compile PostgreSQL supporting
typeof, but that function actually not being present in the C++
compiler. This fixes that by explicitely checking for typeof support
in C++, and then either use that or define typeof ourselves as:
std::remove_reference_t<decltype(x)>
According to the paper that led to adding typeof to the C standard,
that's the C++ equivalent of the C typeof:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2927.htm#existing-decltype
Author: Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Discussion: https://www.postgresql.org/message-id/flat/DGPW5WCFY7WY.1IHCDNIVVT300%2540jeltef.nl
71 lines
1.6 KiB
C++
71 lines
1.6 KiB
C++
/*--------------------------------------------------------------------------
|
|
*
|
|
* test_cplusplusext.cpp
|
|
* Test that PostgreSQL headers compile with a C++ compiler.
|
|
*
|
|
* This file is compiled with a C++ compiler to verify that PostgreSQL
|
|
* headers remain compatible with C++ extensions.
|
|
*
|
|
* Copyright (c) 2025-2026, PostgreSQL Global Development Group
|
|
*
|
|
* IDENTIFICATION
|
|
* src/test/modules/test_cplusplusext/test_cplusplusext.cpp
|
|
*
|
|
* -------------------------------------------------------------------------
|
|
*/
|
|
|
|
extern "C" {
|
|
#include "postgres.h"
|
|
#include "fmgr.h"
|
|
#include "nodes/pg_list.h"
|
|
#include "nodes/primnodes.h"
|
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
PG_FUNCTION_INFO_V1(test_cplusplus_add);
|
|
}
|
|
|
|
StaticAssertDecl(sizeof(int32) == 4, "int32 should be 4 bytes");
|
|
|
|
/*
|
|
* Simple function that returns the sum of two integers. This verifies that
|
|
* C++ extension modules can be loaded and called correctly at runtime.
|
|
*/
|
|
extern "C" Datum
|
|
test_cplusplus_add(PG_FUNCTION_ARGS)
|
|
{
|
|
int32 a = PG_GETARG_INT32(0);
|
|
int32 b = PG_GETARG_INT32(1);
|
|
RangeTblRef *node = makeNode(RangeTblRef);
|
|
RangeTblRef *copy = copyObject(node);
|
|
List *list = list_make1(node);
|
|
|
|
foreach_ptr(RangeTblRef, rtr, list)
|
|
{
|
|
(void) rtr;
|
|
}
|
|
|
|
foreach_node(RangeTblRef, rtr, list)
|
|
{
|
|
(void) rtr;
|
|
}
|
|
|
|
StaticAssertStmt(sizeof(int32) == 4, "int32 should be 4 bytes");
|
|
(void) StaticAssertExpr(sizeof(int64) == 8, "int64 should be 8 bytes");
|
|
|
|
list_free(list);
|
|
pfree(node);
|
|
pfree(copy);
|
|
|
|
switch (a)
|
|
{
|
|
case 1:
|
|
elog(DEBUG1, "1");
|
|
pg_fallthrough;
|
|
case 2:
|
|
elog(DEBUG1, "2");
|
|
break;
|
|
}
|
|
|
|
PG_RETURN_INT32(a + b);
|
|
}
|