Search code examples
c++clangruntime-errorc++23libc++

std::expected in libc++ gives "undefined symbol: _ZTINSt3__119bad_expected_accessIvEE" at runtime


#include <expected>
#include <span>
#include <iostream>

int main() {
    auto e = std::expected<std::span<char>, int>{};
    std::cout << e.value().size() << std::endl;
}

My compiler is clang-19.1.5. Compile the code with the following command:

clang++-19 -std=c++2c -stdlib=libc++ ./toy.cpp -lc++abi -lunwind -lc++

Compiling & linking are ok, but a runtime error is thrown:

./a.out: symbol lookup error: ./a.out: undefined symbol: _ZTINSt3__119bad_expected_accessIvEE

$ nm -D /usr/local/lib/libc++.so.1 | grep access
00000000000607b0 T _ZNKSt18bad_variant_access4whatEv
0000000000054040 T _ZNKSt19bad_optional_access4whatEv
0000000000054060 T _ZNSt12experimental19bad_optional_accessD0Ev
0000000000054050 T _ZNSt12experimental19bad_optional_accessD1Ev
0000000000054050 T _ZNSt12experimental19bad_optional_accessD2Ev
0000000000054020 T _ZNSt19bad_optional_accessD0Ev
0000000000054010 T _ZNSt19bad_optional_accessD1Ev
0000000000054010 T _ZNSt19bad_optional_accessD2Ev
00000000000ee248 D _ZTINSt12experimental19bad_optional_accessE
00000000000ee440 D _ZTISt18bad_variant_access
00000000000ee208 D _ZTISt19bad_optional_access
00000000000b024b R _ZTSNSt12experimental19bad_optional_accessE
00000000000ccded R _ZTSSt18bad_variant_access
00000000000b0233 R _ZTSSt19bad_optional_access
00000000000ee220 D _ZTVNSt12experimental19bad_optional_accessE
00000000000ee418 D _ZTVSt18bad_variant_access
00000000000ee1e0 D _ZTVSt19bad_optional_access

If I change -stdlib=libc++ to -stdlib=libstdc++, then ok.

Why does std::expected of libc++ not work?


Solution

  • This symbol is present in libc++ package version 19.1.6, but not 18.1.8 (I'm going by what's present in Arch Linux package archive since that's my system, but it should be the same for all distros). Upgrading to libc++-19 should do the trick. You can also check which package owns the libc++.so you're currently linking to - if my assumption is correct, it should be libc++ <19.

    If you didn't have this package available in repos, you'd have to upgrade the library manually, but since you already have clang-19, getting libc++-19 the same way shouldn't cause any trouble.

    Note that various parts of the LLVM project are managed as separate packages - clang, llvm, libc++, libc++abi, lld... with their own matching versions. System update updates them all, but they don't all depend on each other, so updating one won't automatically update all.