diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index d1899227c1..86cdddaace 100644
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -30,6 +30,7 @@ endif()
# Create the thrift C++ library
set(thriftcpp_SOURCES
src/thrift/TApplicationException.cpp
+ src/thrift/TConfiguration.cpp
src/thrift/TOutput.cpp
src/thrift/TUuid.cpp
src/thrift/async/TAsyncChannel.cpp
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index dcbcf2c5db..76e57b8235 100644
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -56,6 +56,7 @@ AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(OPENSSL_INCLUDES) -I$(srcdir)/src -D__STDC_FOR
# Define the source files for the module
libthrift_la_SOURCES = src/thrift/TApplicationException.cpp \
+ src/thrift/TConfiguration.cpp \
src/thrift/TOutput.cpp \
src/thrift/TUuid.cpp \
src/thrift/VirtualProfiling.cpp \
diff --git a/lib/cpp/libthrift.vcxproj b/lib/cpp/libthrift.vcxproj
index 7fcccfe99e..7d2aa58bc6 100644
--- a/lib/cpp/libthrift.vcxproj
+++ b/lib/cpp/libthrift.vcxproj
@@ -56,6 +56,7 @@
+
diff --git a/lib/cpp/libthrift.vcxproj.filters b/lib/cpp/libthrift.vcxproj.filters
index 4b2ba3b278..6e9160af65 100644
--- a/lib/cpp/libthrift.vcxproj.filters
+++ b/lib/cpp/libthrift.vcxproj.filters
@@ -7,6 +7,7 @@
+
transport
diff --git a/lib/cpp/src/thrift/TConfiguration.cpp b/lib/cpp/src/thrift/TConfiguration.cpp
new file mode 100644
index 0000000000..5b767ddf48
--- /dev/null
+++ b/lib/cpp/src/thrift/TConfiguration.cpp
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include
+
+namespace apache {
+namespace thrift {
+
+// Binding one of these constants to a reference, as std::make_shared or
+// std::min do, needs a definition before C++17.
+const int TConfiguration::DEFAULT_MAX_MESSAGE_SIZE;
+const int TConfiguration::DEFAULT_MAX_FRAME_SIZE;
+const int TConfiguration::DEFAULT_RECURSION_DEPTH;
+
+}
+} // apache::thrift
diff --git a/lib/cpp/test/TTransportFactoryConfigTest.cpp b/lib/cpp/test/TTransportFactoryConfigTest.cpp
index 10ad919625..b0d48bae85 100644
--- a/lib/cpp/test/TTransportFactoryConfigTest.cpp
+++ b/lib/cpp/test/TTransportFactoryConfigTest.cpp
@@ -278,3 +278,17 @@ BOOST_AUTO_TEST_CASE(test_framed_transport_default_constructor_initialises_max_f
TFramedTransport wrapped(std::make_shared(), config);
BOOST_CHECK_EQUAL(wrapped.getMaxFrameSize(), static_cast(kMaxFrameSize));
}
+
+// Binding a default to a reference or taking its address needs the library to
+// define it. Reading the addresses through volatile pointers keeps an
+// optimising compiler from folding the references away (THRIFT-6213).
+BOOST_AUTO_TEST_CASE(test_configuration_defaults_are_defined) {
+ const int* volatile maxMessageSize = &TConfiguration::DEFAULT_MAX_MESSAGE_SIZE;
+ const int* volatile maxFrameSize = &TConfiguration::DEFAULT_MAX_FRAME_SIZE;
+ const int* volatile recursionDepth = &TConfiguration::DEFAULT_RECURSION_DEPTH;
+
+ const TConfiguration config;
+ BOOST_CHECK_EQUAL(*maxMessageSize, config.getMaxMessageSize());
+ BOOST_CHECK_EQUAL(*maxFrameSize, config.getMaxFrameSize());
+ BOOST_CHECK_EQUAL(*recursionDepth, config.getRecursionLimit());
+}