Skip to content

Commit 55eb0d3

Browse files
[Velox] Fix Iceberg writer aggregate-init build failure on macOS C++20 libc++ (#12115)
Two call sites in cpp/velox/compute/iceberg/IcebergWriter.cc construct aggregate types via paren-init with multiple arguments: fields.emplace_back(name, type, transform, parameter); // line 311 return WriteStats(numWrittenBytes, // line 262 numWrittenFiles, writeIOTimeNs, writeWallNs); Both target types are pure aggregate structs without a user-defined constructor: // Velox: velox/connectors/hive/iceberg/PartitionSpec.h struct IcebergPartitionSpec::Field { std::string name; TypePtr type; TransformType transformType; std::optional<int32_t> parameter; }; // Gluten: cpp/velox/compute/iceberg/IcebergWriter.h struct WriteStats { uint64_t numWrittenBytes{0}; uint32_t numWrittenFiles{0}; uint64_t writeIOTimeNs{0}; uint64_t writeWallNs{0}; ... }; C++20 P0960R3 made aggregates initializable via paren-init at the language level, but the standard library implementation of std::construct_at (which std::vector::emplace_back routes through to do in-place construction) is uneven across stdlibs: - libstdc++ (Linux GCC): construct_at accepts aggregate paren-init, so emplace_back(a, b, c, d) compiles for aggregate types. - libc++ (Apple Clang 17, macOS): construct_at still requires a real constructor, so the substitution fails: error: no matching function for call to 'construct_at' note: candidate template ignored: substitution failure [with _Tp = IcebergPartitionSpec::Field, _Args = ...]: no matching constructor for initialization of 'IcebergPartitionSpec::Field' Result: builds with --enable_enhanced_features=ON on macOS abort hard at IcebergWriter.cc.cpp.o (~156/217) before producing libgluten.dylib, blocking any macOS user from running the Iceberg writer integration that this gate adds. The fix is a minimal style change at the two call sites — switch from paren-init to brace-init, which is aggregate initialization on every C++17/20 toolchain (libstdc++, libc++, MSVC): fields.push_back({name, type, transform, parameter}); return WriteStats{numWrittenBytes, numWrittenFiles, ...}; Linux libstdc++ continues to compile cleanly: brace-init resolves to the same aggregate initialization the paren-init form selected via P0960. Zero runtime change, identical field-by-field initialization. Verification: - macOS 14 arm64 + Apple Clang 17 + --enable_enhanced_features=ON: cpp build now reaches 217/217 (was 156/217 before this fix). - cpp ctest matrix on the same configuration: 5539 / 5539 pass, including the enhanced-only velox_iceberg_test executable. - Linux x86_64 build remains green; brace-init for aggregates is unchanged in libstdc++. Co-authored-by: Kent Yao <kentyao@microsoft.com>
1 parent 53dc27d commit 55eb0d3

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

cpp/velox/compute/iceberg/IcebergWriter.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,11 @@ WriteStats IcebergWriter::writeStats() const {
259259
const auto currentTimeNs = getCurrentTimeNano();
260260
VELOX_CHECK_GE(currentTimeNs, createTimeNs_);
261261
const auto sinkStats = dataSink_->stats();
262-
return WriteStats(
262+
return WriteStats{
263263
sinkStats.numWrittenBytes,
264264
sinkStats.numWrittenFiles,
265265
sinkStats.writeIOTimeUs * 1000,
266-
currentTimeNs - createTimeNs_);
266+
currentTimeNs - createTimeNs_};
267267
}
268268

269269
std::shared_ptr<const iceberg::IcebergPartitionSpec>
@@ -308,7 +308,7 @@ parseIcebergPartitionSpec(const uint8_t* data, const int32_t length, RowTypePtr
308308
parameter = protoField.parameter();
309309
}
310310

311-
fields.emplace_back(protoField.name(), rowType->findChild(protoField.name()), transform, parameter);
311+
fields.push_back({protoField.name(), rowType->findChild(protoField.name()), transform, parameter});
312312
}
313313

314314
return std::make_shared<iceberg::IcebergPartitionSpec>(protoSpec.spec_id(), fields);

0 commit comments

Comments
 (0)