TL;DR

  1. 当前 DuckDB main 要求 C++17 或更高。C++11 已经不是 supported baseline。
  2. 这不只是 build system 偏好。公共头文件已经使用 C++17 特性。
  3. 关键特性包括 std::string_view、std::optional、if constexpr、type-traits _v helper、structured binding,以及少量 std::variant。

直接测试

DuckDB 的 Makefile 仍然保留了 CXX_STANDARD override:

ifneq (${CXX_STANDARD}, )
        CMAKE_VARS:=${CMAKE_VARS} -DCMAKE_CXX_STANDARD="${CXX_STANDARD}"
endif

所以可以直接试:

CXX_STANDARD=11 GEN=ninja make debug

在测试的 DuckDB main snapshot 上,这会在 CMake 配置阶段失败:

DuckDB requires C++17 or higher; got CMAKE_CXX_STANDARD=11.
Pass -DCMAKE_CXX_STANDARD=17 (or higher), or unset it to use the default.

工程边界很明确。DuckDB 接受 C++17、C++20、C++23、C++26,不接受 C++11。

为什么会有这个边界

CMake 错误只能证明 C++11 不被支持,还不能解释源码为什么需要 C++17。

所以我生成了正常 C++17 的 compile commands,再把部分真实命令改成 -std=c++11 -fsyntax-only。第一批硬错误就来自公共头文件:

src/include/duckdb/common/helper.hpp: error: 'is_same_v' is not a member of 'std'
src/include/duckdb/common/identifier.hpp: error: 'string_view' in namespace 'std' does not name a type
src/include/duckdb/common/optional.hpp: error: 'nullopt' has not been declared in 'std'
src/include/duckdb/common/optional.hpp: error: 'optional' has not been declared in 'std'
src/include/duckdb/common/types/value.hpp: error: 'optional' does not name a type

也就是说,当前 DuckDB 不是“基本还能用 C++11 编”。公共头文件刚进入编译不久就失败。

C++17 使用已经分散到源码里

同一个 snapshot 的源码粗略扫描结果:

特性粗略命中数典型位置
if constexpr185cast、aggregate、recursive CTE、template executor
std::string_view / string_view111identifier、Value、C API v2、setting
std::optional19common optional wrapper、cast/result path
structured binding17bind helper、copy path、function serialization
std::variant1bitpacking compression state

这些理由比“现代 C++ 更好”更具体。

std::string_view 减少不必要的字符串分配和拷贝。数据库里 identifier、setting、function name、literal buffer 到处都是。

std::optional 明确表达“可能没有值”,比 sentinel、裸指针或额外 boolean 更清楚。

if constexpr 对 DuckDB 的 template-heavy primitive 很重要。普通 if 要求两边分支都能通过类型检查;if constexpr 可以在编译期丢掉不适用的分支。

_v type-traits helper 本身不大,但很常见。C++11 可以写 std::is_same<T, U>::value,但当前 DuckDB 已经按 C++17 写了。

边界

这里的结论很窄:

C++11 足够启动项目。
C++17 现在已经是当前 DuckDB 源码能被直接表达和编译的最低边界。

这不表示每个 C++17 特性都适合数据库代码。它只说明当前 DuckDB 已经过了“还能现实兼容 C++11”的线。