Я не знаю библиотеку, поэтому не могу дать однозначного ответа. Я буду идти по коду в https://github.com/cwida/duckdb.
В соответствии с сообщением об ошибке в проблемном коде в строке 332 из test/sql/capi/test_capi.cpp
, что:
REQUIRE(stmt != NULL);
REQUIRE
является макросом из библиотеки модульного тестирования Catch2, который выполняет некоторые действия, чтобы разобрать данное ему выражение. Важная часть заключается в том, что stmt != NULL
на самом деле будет выполняться не сразу, а только через косвенное обращение к функции.
stmt
объявлено в строке 324 как
duckdb_prepared_statement stmt = nullptr;
и duckdb_prepared_statement
является typedef в строке 94 из src/include/duckdb.h
:
typedef void *duckdb_prepared_statement;
Следовательно, задача проблемной строки - проверить, является ли stmt
по-прежнему nullptr
после некоторых промежуточных операций.
Обычно stmt != NULL
было бы хорошо для этого. Однако поскольку макрос Catch2 вводит промежуточные вызовы функций, а не оценивает это выражение напрямую, неявные преобразования, характерные для литерала, не применяются.
В частности, NULL
в соответствии со стандартом является либо prvalue типа std::nullptr_t
или целочисленный литерал со значением 0. Какой именно из них (и какой целочисленный тип) определяется реализацией.
Сравнение целых чисел и указателей обычно запрещено, однако целочисленные литералы со значением ноль имеют специальное исключение, позволяющееони должны быть неявно преобразованы в нулевой указатель любого типа указателя. Это то, что произойдет, если stmt != NULL
будет оцениваться напрямую.
Однако из-за прерывания Catch2 NULL
сначала передается, а затем сравнивается через переменную с stmt
, что делает специальныйнулевое буквальное правило больше не применяется. Поэтому сравнение stmt
с NULL
через REQUIRE
не удастся, если NULL
является целочисленным литералом в текущей реализации.
Catch2 действительно учитывает эту проблему и существуют перегрузки для compareNotEqual
вthird_party/catch/catch.hpp
, который учитывает случай, когда NULL
является целочисленным литералом нулевого типа типа int
или long
, но по какой-то причине случай long long
не рассматривается. Я не знаю, является ли это проблемой с Catch2 или это только в клонированной версии, включенной в duckdb.
Итак, если реализация использует нулевой литерал типа long long
для NULL
,тогда произойдет ошибка, которую вы наблюдали.
Действительно, duckdb должен использовать nullptr
вместо NULL
(как это происходит при инициализации), что не имеет этих проблем и было добавлено в язык из-за того, чтоэти проблемы.
Полагаю, вы можете просто попытаться решить эту проблему, заменив NULL
на nullptr
(возможно, и в других тестовых случаях).
Однако проблемный код тольков файлах, которые сами являются модульными тестами для фактического кода библиотеки. Так что должна быть какая-то опция cmake или make, которая отключит сборку модульных тестов, чтобы вы могли игнорировать эту конкретную ошибку, надеясь, что она не встречается нигде в реальном коде библиотеки.
ЕслиЯ был прав в своих оценках, возможно, вы захотите подать отчет об ошибке с помощью duckdb, предполагая, что они в первую очередь поддерживают вашу платформу.