Skip to content

Commit 9d65981

Browse files
authored
ARROW-17545: [C++][CI] Mandate C++17 instead of C++11 (apache#13991)
This PR switches our build system to require C++17 instead of C++11. Because the conda packaging jobs are out of sync with the conda-forge files, the Windows conda packaging jobs are broken with this change. The related task (sync conda packaging files with conda-forge) is tracked in ARROW-17635. Authored-by: Antoine Pitrou <[email protected]> Signed-off-by: Antoine Pitrou <[email protected]>
1 parent c9844f0 commit 9d65981

File tree

73 files changed

+284
-189
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+284
-189
lines changed

.env

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ ARROW_R_DEV=TRUE
8686
R_PRUNE_DEPS=FALSE
8787
TZ=UTC
8888

89-
# -1 does not attempt to install a devtoolset version, any positive integer will install devtoolset-n
90-
DEVTOOLSET_VERSION=-1
89+
# Any non-empty string will install devtoolset-${DEVTOOLSET_VERSION}
90+
DEVTOOLSET_VERSION=
9191

9292
# Used through docker-compose.yml and serves as the default version for the
9393
# ci/scripts/install_vcpkg.sh script. Prefer to use short SHAs to keep the

.github/workflows/r.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,13 @@ jobs:
119119
fail-fast: false
120120
matrix:
121121
config:
122-
- { org: "rstudio", image: "r-base", tag: "4.0-centos7" }
123-
- { org: "rhub", image: "debian-gcc-devel", tag: "latest" }
122+
- { org: "rstudio", image: "r-base", tag: "4.0-centos7", devtoolset: "8" }
123+
- { org: "rhub", image: "debian-gcc-devel", tag: "latest", devtoolset: "" }
124124
env:
125125
R_ORG: ${{ matrix.config.org }}
126126
R_IMAGE: ${{ matrix.config.image }}
127127
R_TAG: ${{ matrix.config.tag }}
128+
DEVTOOLSET_VERSION: ${{ matrix.config.devtoolset }}
128129
steps:
129130
- name: Checkout Arrow
130131
uses: actions/checkout@v3
@@ -184,11 +185,6 @@ jobs:
184185
run: |
185186
ci/scripts/ccache_setup.sh
186187
echo "CCACHE_DIR=$(cygpath --absolute --windows ccache)" >> $GITHUB_ENV
187-
# We must enable actions/cache before r-lib/actions/setup-r to ensure
188-
# using system tar instead of tar provided by Rtools.
189-
# We can use tar provided by Rtools when we drop support for Rtools 3.5.
190-
# Because Rtools 4.0 or later has zstd. actions/cache requires zstd
191-
# when tar is GNU tar.
192188
- name: Cache ccache
193189
uses: actions/cache@v2
194190
with:
@@ -268,8 +264,6 @@ jobs:
268264
with:
269265
r-version: ${{ matrix.config.rversion }}
270266
rtools-version: ${{ matrix.config.rtools }}
271-
# RSPM keeps install times short for 3.6
272-
use-public-rspm: true
273267
Ncpus: 2
274268
- uses: r-lib/actions/setup-r-dependencies@v2
275269
env:

c_glib/meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ project('arrow-glib', 'c', 'cpp',
2121
license: 'Apache-2.0',
2222
default_options: [
2323
'c_std=c99',
24-
'cpp_std=c++11',
24+
'cpp_std=c++17',
2525
])
2626

2727
version = '10.0.0-SNAPSHOT'

ci/conan/all/test_package/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ find_package(Arrow REQUIRED)
3030

3131
add_executable(${PROJECT_NAME} test_package.cpp)
3232
target_link_libraries(${PROJECT_NAME} arrow::arrow)
33-
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
33+
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
3434
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_JEMALLOC)

ci/docker/linux-r.dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ENV R_BIN=${r_bin}
2727
ARG r_dev=FALSE
2828
ENV ARROW_R_DEV=${r_dev}
2929

30-
ARG devtoolset_version=-1
30+
ARG devtoolset_version=
3131
ENV DEVTOOLSET_VERSION=${devtoolset_version}
3232

3333
ARG r_prune_deps=FALSE

ci/scripts/cpp_build.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ cmake \
142142
-DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE:-OFF} \
143143
-DCMAKE_C_FLAGS="${CFLAGS:-}" \
144144
-DCMAKE_CXX_FLAGS="${CXXFLAGS:-}" \
145-
-DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-11}" \
145+
-DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-17}" \
146146
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR:-lib} \
147147
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX:-${ARROW_HOME}} \
148148
-DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD:-OFF} \

ci/scripts/r_docker_configure.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ if [ ${R_CUSTOM_CCACHE} = "true" ]; then
5757
CCACHE=ccache
5858
CC=\$(CCACHE) gcc\$(VER)
5959
CXX=\$(CCACHE) g++\$(VER)
60-
CXX11=\$(CCACHE) g++\$(VER)" >> ~/.R/Makevars
60+
CXX17=\$(CCACHE) g++\$(VER)" >> ~/.R/Makevars
6161

6262
mkdir -p ~/.ccache/
6363
echo "max_size = 5.0G
@@ -69,7 +69,7 @@ fi
6969

7070
# Special hacking to try to reproduce quirks on centos using non-default build
7171
# tooling.
72-
if [[ "$DEVTOOLSET_VERSION" -gt 0 ]]; then
72+
if [[ -n "$DEVTOOLSET_VERSION" ]]; then
7373
$PACKAGE_MANAGER install -y centos-release-scl
7474
$PACKAGE_MANAGER install -y "devtoolset-$DEVTOOLSET_VERSION"
7575
fi

ci/scripts/r_test.sh

+14-6
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,21 @@ pushd ${source_dir}
2626

2727
printenv
2828

29+
if [[ -n "$DEVTOOLSET_VERSION" ]]; then
30+
# enable the devtoolset version to use it
31+
source /opt/rh/devtoolset-$DEVTOOLSET_VERSION/enable
32+
33+
# Build images which require the devtoolset don't have CXX17 variables
34+
# set as the system compiler doesn't support C++17
35+
mkdir -p ~/.R
36+
echo "CC = $(which gcc) -fPIC" >> ~/.R/Makevars
37+
echo "CXX17 = $(which g++) -fPIC" >> ~/.R/Makevars
38+
echo "CXX17STD = -std=c++17" >> ~/.R/Makevars
39+
echo "CXX17FLAGS = ${CXX11FLAGS}" >> ~/.R/Makevars
40+
fi
41+
2942
# Run the nixlibs.R test suite, which is not included in the installed package
30-
${R_BIN} -e 'setwd("tools"); testthat::test_dir(".")'
43+
${R_BIN} -e 'setwd("tools"); testthat::test_dir(".")'
3144

3245
# Before release, we always copy the relevant parts of the cpp source into the
3346
# package. In some CI checks, we will use this version of the source:
@@ -77,11 +90,6 @@ export ARROW_DEBUG_MEMORY_POOL=trap
7790
export TEXMFCONFIG=/tmp/texmf-config
7891
export TEXMFVAR=/tmp/texmf-var
7992

80-
if [[ "$DEVTOOLSET_VERSION" -gt 0 ]]; then
81-
# enable the devtoolset version to use it
82-
source /opt/rh/devtoolset-$DEVTOOLSET_VERSION/enable
83-
fi
84-
8593
# Make sure we aren't writing to the home dir (CRAN _hates_ this but there is no official check)
8694
BEFORE=$(ls -alh ~/)
8795

cpp/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -561,10 +561,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARROW_CXXFLAGS}")
561561
# C++ specific flags.
562562
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CXX_COMMON_FLAGS} ${ARROW_CXXFLAGS}")
563563

564-
# Remove --std=c++11 to avoid errors from C compilers
565-
string(REPLACE "-std=c++11" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
564+
# Remove --std=c++17 to avoid errors from C compilers
565+
string(REPLACE "-std=c++17" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
566566

567-
# Add C++-only flags, like -std=c++11
567+
# Add C++-only flags, like -std=c++17
568568
set(CMAKE_CXX_FLAGS "${CXX_ONLY_FLAGS} ${CMAKE_CXX_FLAGS}")
569569

570570
# ASAN / TSAN / UBSAN

cpp/build-support/update-flatbuffers.sh

-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ OUT_DIR="$SOURCE_DIR/generated"
3333
FILES=($(find $FORMAT_DIR -name '*.fbs'))
3434
FILES+=("$SOURCE_DIR/arrow/ipc/feather.fbs")
3535

36-
# add compute ir files
37-
FILES+=($(find "$TOP/experimental/computeir" -name '*.fbs'))
38-
3936
$FLATC --cpp --cpp-std c++11 \
4037
--scoped-enums \
4138
-o "$OUT_DIR" \

cpp/cmake_modules/SetupCxxFlags.cmake

+10-8
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,14 @@ if(NOT DEFINED CMAKE_C_STANDARD)
122122
set(CMAKE_C_STANDARD 11)
123123
endif()
124124

125-
# This ensures that things like c++11 get passed correctly
125+
# This ensures that things like c++17 get passed correctly
126126
if(NOT DEFINED CMAKE_CXX_STANDARD)
127-
set(CMAKE_CXX_STANDARD 11)
127+
set(CMAKE_CXX_STANDARD 17)
128+
elseif(${CMAKE_CXX_STANDARD} VERSION_LESS 17)
129+
message(FATAL_ERROR "Cannot set a CMAKE_CXX_STANDARD smaller than 17")
128130
endif()
129131

130-
# We require a C++11 compliant compiler
132+
# We require a C++17 compliant compiler
131133
set(CMAKE_CXX_STANDARD_REQUIRED ON)
132134

133135
# ARROW-6848: Do not use GNU (or other CXX) extensions
@@ -440,11 +442,11 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STRE
440442
# Don't complain about optimization passes that were not possible
441443
set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-pass-failed")
442444

443-
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
444-
# Depending on the default OSX_DEPLOYMENT_TARGET (< 10.9), libstdc++ may be
445-
# the default standard library which does not support C++11. libc++ is the
446-
# default from 10.9 onward.
447-
set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -stdlib=libc++")
445+
# Avoid clang / libc++ error about C++17 aligned allocation on macOS.
446+
# See https://chromium.googlesource.com/chromium/src/+/eee44569858fc650b635779c4e34be5cb0c73186%5E%21/#F0
447+
# for details.
448+
if(APPLE)
449+
set(CXX_ONLY_FLAGS "${CXX_ONLY_FLAGS} -fno-aligned-new")
448450
endif()
449451
endif()
450452

cpp/cmake_modules/ThirdpartyToolchain.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -2088,7 +2088,7 @@ macro(build_benchmark)
20882088
endif()
20892089

20902090
if(NOT MSVC)
2091-
set(GBENCHMARK_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS} -std=c++11")
2091+
set(GBENCHMARK_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS} -std=c++17")
20922092
endif()
20932093

20942094
if(APPLE AND (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID

cpp/examples/minimal_build/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ option(ARROW_LINK_SHARED "Link to the Arrow shared library" ON)
2424
find_package(Arrow REQUIRED)
2525

2626
if(NOT DEFINED CMAKE_CXX_STANDARD)
27-
set(CMAKE_CXX_STANDARD 11)
27+
set(CMAKE_CXX_STANDARD 17)
2828
endif()
2929

30-
# We require a C++11 compliant compiler
30+
# We require a C++17 compliant compiler
3131
set(CMAKE_CXX_STANDARD_REQUIRED ON)
3232

3333
if(NOT DEFINED CMAKE_BUILD_TYPE)

cpp/examples/parquet/parquet_arrow/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ include(GNUInstallDirs)
2626

2727
option(PARQUET_LINK_SHARED "Link to the Parquet shared library" ON)
2828

29-
# This ensures that things like gnu++11 get passed correctly
29+
# This ensures that things like -std=gnu++... get passed correctly
3030
if(NOT DEFINED CMAKE_CXX_STANDARD)
31-
set(CMAKE_CXX_STANDARD 11)
31+
set(CMAKE_CXX_STANDARD 17)
3232
endif()
3333

34-
# We require a C++11 compliant compiler
34+
# We require a C++17 compliant compiler
3535
set(CMAKE_CXX_STANDARD_REQUIRED ON)
3636

3737
# Look for installed packages the system

cpp/src/arrow/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,8 @@ endif()
636636

637637
foreach(LIB_TARGET ${ARROW_LIBRARIES})
638638
target_compile_definitions(${LIB_TARGET} PRIVATE ARROW_EXPORTING)
639+
# C++17 is required to compile against Arrow C++ headers and libraries
640+
target_compile_features(${LIB_TARGET} PUBLIC cxx_std_17)
639641
endforeach()
640642

641643
if(ARROW_WITH_BACKTRACE)

cpp/src/arrow/dataset/file_csv.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ class ARROW_DS_EXPORT CsvFileWriteOptions : public FileWriteOptions {
9898
std::shared_ptr<csv::WriteOptions> write_options;
9999

100100
protected:
101-
using FileWriteOptions::FileWriteOptions;
101+
explicit CsvFileWriteOptions(std::shared_ptr<FileFormat> format)
102+
: FileWriteOptions(std::move(format)) {}
102103

103104
friend class CsvFileFormat;
104105
};

cpp/src/arrow/dataset/file_ipc.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ class ARROW_DS_EXPORT IpcFileWriteOptions : public FileWriteOptions {
9090
std::shared_ptr<const KeyValueMetadata> metadata;
9191

9292
protected:
93-
using FileWriteOptions::FileWriteOptions;
93+
explicit IpcFileWriteOptions(std::shared_ptr<FileFormat> format)
94+
: FileWriteOptions(std::move(format)) {}
9495

9596
friend class IpcFileFormat;
9697
};

cpp/src/arrow/dataset/file_parquet.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ class ARROW_DS_EXPORT ParquetFileWriteOptions : public FileWriteOptions {
226226
std::shared_ptr<parquet::ArrowWriterProperties> arrow_writer_properties;
227227

228228
protected:
229-
using FileWriteOptions::FileWriteOptions;
229+
explicit ParquetFileWriteOptions(std::shared_ptr<FileFormat> format)
230+
: FileWriteOptions(std::move(format)) {}
230231

231232
friend class ParquetFileFormat;
232233
};

cpp/src/arrow/memory_pool.cc

+4
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ class DebugAllocator {
229229
*out = memory_pool::internal::kZeroSizeArea;
230230
} else {
231231
ARROW_ASSIGN_OR_RAISE(int64_t raw_size, RawSize(size));
232+
DCHECK(raw_size > size) << "bug in raw size computation: " << raw_size
233+
<< " for size " << size;
232234
RETURN_NOT_OK(WrappedAllocator::AllocateAligned(raw_size, out));
233235
InitAllocatedArea(*out, size);
234236
}
@@ -250,6 +252,8 @@ class DebugAllocator {
250252
return Status::OK();
251253
}
252254
ARROW_ASSIGN_OR_RAISE(int64_t raw_new_size, RawSize(new_size));
255+
DCHECK(raw_new_size > new_size)
256+
<< "bug in raw size computation: " << raw_new_size << " for size " << new_size;
253257
RETURN_NOT_OK(
254258
WrappedAllocator::ReallocateAligned(old_size + kOverhead, raw_new_size, ptr));
255259
InitAllocatedArea(*ptr, new_size);

cpp/src/arrow/util/aligned_storage.h

+19
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,26 @@ class AlignedStorage {
123123
}
124124

125125
private:
126+
#if !defined(__clang__) && defined(__GNUC__) && defined(__i386__)
127+
// Workaround for GCC bug on i386:
128+
// alignof(int64 | float64) can give different results depending on the
129+
// compilation context, leading to internal ABI mismatch manifesting
130+
// in incorrect propagation of Result<int64 | float64> between
131+
// compilation units.
132+
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88115)
133+
static constexpr size_t alignment() {
134+
if (std::is_integral_v<T> && sizeof(T) == 8) {
135+
return 4;
136+
} else if (std::is_floating_point_v<T> && sizeof(T) == 8) {
137+
return 4;
138+
}
139+
return alignof(T);
140+
}
141+
142+
typename std::aligned_storage<sizeof(T), alignment()>::type data_;
143+
#else
126144
typename std::aligned_storage<sizeof(T), alignof(T)>::type data_;
145+
#endif
127146
};
128147

129148
} // namespace internal

cpp/src/arrow/util/int_util_test.cc

+55
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <algorithm>
1919
#include <cstdint>
20+
#include <limits>
2021
#include <random>
2122
#include <string>
2223
#include <utility>
@@ -594,5 +595,59 @@ TEST(CheckIntegersInRange, UnsignedInts) {
594595
CheckInRangeFails(uint64(), "[0, 10000000000, 10000000000]", "[0, 9999999999]");
595596
}
596597

598+
template <typename T>
599+
class TestAddWithOverflow : public ::testing::Test {
600+
public:
601+
void CheckOk(T a, T b, T expected_result = {}) {
602+
ARROW_SCOPED_TRACE("a = ", a, ", b = ", b);
603+
T result;
604+
ASSERT_FALSE(AddWithOverflow(a, b, &result));
605+
ASSERT_EQ(result, expected_result);
606+
}
607+
608+
void CheckOverflow(T a, T b) {
609+
ARROW_SCOPED_TRACE("a = ", a, ", b = ", b);
610+
T result;
611+
ASSERT_TRUE(AddWithOverflow(a, b, &result));
612+
}
613+
};
614+
615+
using SignedIntegerTypes = ::testing::Types<int8_t, int16_t, int32_t, int64_t>;
616+
617+
TYPED_TEST_SUITE(TestAddWithOverflow, SignedIntegerTypes);
618+
619+
TYPED_TEST(TestAddWithOverflow, Basics) {
620+
using T = TypeParam;
621+
622+
const T almost_max = std::numeric_limits<T>::max() - T{2};
623+
const T almost_min = std::numeric_limits<T>::min() + T{2};
624+
625+
this->CheckOk(T{1}, T{2}, T{3});
626+
this->CheckOk(T{-1}, T{2}, T{1});
627+
this->CheckOk(T{-1}, T{-2}, T{-3});
628+
629+
this->CheckOk(almost_min, T{0}, almost_min);
630+
this->CheckOk(almost_min, T{-2}, almost_min - T{2});
631+
this->CheckOk(almost_min, T{1}, almost_min + T{1});
632+
this->CheckOverflow(almost_min, T{-3});
633+
this->CheckOverflow(almost_min, almost_min);
634+
635+
this->CheckOk(almost_max, T{0}, almost_max);
636+
this->CheckOk(almost_max, T{2}, almost_max + T{2});
637+
this->CheckOk(almost_max, T{-1}, almost_max - T{1});
638+
this->CheckOverflow(almost_max, T{3});
639+
this->CheckOverflow(almost_max, almost_max);
640+
641+
// In 2's complement, almost_min == - almost_max - 1
642+
this->CheckOk(almost_min, almost_max, T{-1});
643+
this->CheckOk(almost_max, almost_min, T{-1});
644+
this->CheckOk(almost_min - T{1}, almost_max, T{-2});
645+
this->CheckOk(almost_min + T{1}, almost_max, T{0});
646+
this->CheckOk(almost_min + T{2}, almost_max, T{1});
647+
this->CheckOk(almost_min, almost_max - T{1}, T{-2});
648+
this->CheckOk(almost_min, almost_max + T{1}, T{0});
649+
this->CheckOk(almost_min, almost_max + T{2}, T{1});
650+
}
651+
597652
} // namespace internal
598653
} // namespace arrow

cpp/src/arrow/util/launder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
namespace arrow {
2323
namespace internal {
2424

25-
#if __cplusplus >= 201703L
25+
#if __cpp_lib_launder
2626
using std::launder;
2727
#else
2828
template <class T>

0 commit comments

Comments
 (0)