Skip to content

Darwin arm64 build fails to link optional uint64 output #50178

Description

@astandrik

Problem

On Darwin arm64, linking code that writes std::optional<uint64_t> to an IOutputStream fails with an undefined symbol:

ld64.lld: error: undefined symbol: void Out<std::__y1::optional<unsigned long long>>(IOutputStream&, std::__y1::optional<unsigned long long> const&)

This is currently reachable from ydb/library/yql/providers/pq/async_io/dq_pq_read_actor.cpp, which logs a std::optional<uint64_t> value.

Steps to reproduce

Tested on Apple Silicon at main commit 2de8cf3cfb50dcb0e87661142affb799042cfa98.

  1. Add this focused case to the TestOutput suite in util/stream/output_ut.cpp:

    Y_UNIT_TEST(TestOptionalUint64) {
        UNIT_ASSERT_VALUES_EQUAL(TStringBuilder() << std::optional<std::uint64_t>{42}, "42");
        UNIT_ASSERT_VALUES_EQUAL(TStringBuilder() << std::optional<std::uint64_t>{}, "(NULL)");
    }
  2. Build the unit-test binary:

    ./ya make --build relwithdebinfo util/stream/ut

The link fails with the undefined symbol shown above. The same missing symbol was also observed at the final link of ydb/core/kqp/ut/query through the existing PQ caller.

Root cause

util/stream/output.cpp explicitly instantiates optional output for ui64. On 64-bit Darwin, ui64 is unsigned long, while Clang defines uint64_t as unsigned long long, so these are distinct template specializations. The file already carries an analogous Darwin arm64 specialization for std::int64_t, but not for std::uint64_t.

Fix

Add DEF_OPTIONAL(std::uint64_t) next to the existing Darwin arm64 std::int64_t specialization and cover both present and empty optional values with a focused regression test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions