0

对于我的硕士学位,我需要在一个名为 daddb 的数据库上工作(它在 git hub 上)。通常在 Linux 上,您可以简单地克隆它并“制作”它来安装。

安装 CMake 和 Cygwin 后,我在 Windows 上也感到厌烦。

但是在编译过程中我得到了错误

'DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1445:96:
错误:ISO C++ 禁止指针和整数之间的比较 [-fpermissive]

 auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }'

由于我怀疑duckdb的创建者确实把这件事搞砸了,我认为尝试将C文件编译为C++文件时可能会出现编译器错误。

我的主要问题是:如何在 Windows 上配置 make 命令以阻止它产生此错误?

我在安装了 gcc 5.1 和当前 cmake 的 Windows 7 和 10 系统上都尝试了它,并且都产生了这个错误。

编辑:这是完整的错误文本

[ 87%] 构建 CXX 对象 test/sql/capi/CMakeFiles/test_sql_capi.dir/ub_test_sql_capi.cpp.obj 在来自 C:/duckdb/test/sql/capi/test_capi.cpp:1:0 的文件中,来自 test_capi。 cpp:0:

C:/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp: 在 'bool >Catch::compareNotEqual(const LhsT&, RhsT&&) [with LhsT = void*; RhsT = const >long long int&]':

C:/DB/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1471:37: 需要来自 'const >Catch::BinaryExpr Catch::ExprLhs::operator!=(const >RhsT&) [with RhsT = long long int; LhsT = void* const&]'

C:/DB/duckdb/test/sql/capi/test_capi.cpp:332:2: 从这里需要 C:/DB/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1445:96: 错误: ISO C++ 禁止比较 > 在指针和整数之间 [-fpermissive] auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return >static_cast(lhs != rhs); }

我只在路径等中编辑了我的用户名。

4

3 回答 3

2

我不知道图书馆,所以我不能给出肯定的答案。我将按照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是第 94 行中的 typedef src/include/duckdb.h

typedef void *duckdb_prepared_statement;

因此,有问题的行的目的是检查在一些中间操作之后是否stmt仍然是 a 。nullptr

通常stmt != NULL会很好。但是,由于 Catch2 宏引入了中间函数调用,而不是直接评估此表达式,因此不应用特定于文字的隐式转换。

特别NULL是根据标准,类型的纯右std::nullptr_t值或值为 0 的整数文字。这些中的哪一个(以及哪个整数类型)是实现定义的。

通常禁止比较整数和指针,但是值为零的整数文字有一个特殊的例外,允许它们被隐式转换为任何指针类型的空指针。这就是如果stmt != NULL直接评估会发生的情况。

然而,由于 Catch2 的插入,NULL首先传递,然后通过变量与 to 进行比较stmt,这使得特殊的零文字规则不再适用。因此,如果当前实现中是整数文字,则stmtNULLthrough的比较REQUIRE将失败。NULL

Catch2 确实考虑了这个问题,并且有 for compareNotEqualin的重载处理了or类型的零整数文字的third_party/catch/catch.hpp情况,但由于某种原因,不考虑 of 的情况。不知道这是否是 Catch2 的问题,还是仅存在于duckdb 中包含的克隆版本中。NULLintlonglong long

因此,如果实现使用 for 类型的零字面量long longNULL那么您观察到的错误将会发生。

真正的duckdb应该使用nullptr代替NULL(就像它在初始化中所做的那样),它没有这些问题并且正是因为这些问题而被添加到语言中。

我想你可以简单地尝试通过替换来解决这个问题NULLnullptr也许在其他测试用例中也是如此)。

但是,有问题的代码仅存在于文件中,这些文件本身就是实际库代码的单元测试。所以应该有一些 cmake 或 make 选项将禁用构建单元测试,这样你就可以忽略这个特定的错误,希望它不会出现在实际库代码的任何地方。

如果我的评估是正确的,那么您可能需要考虑使用duckdb 提交一个错误报告,假设他们首先支持您的平台。

于 2019-10-21T16:20:50.610 回答
1

与使用 Cygwin 相比,使用 CMake 结合 Visual Studio 编译项目可能更容易。这是作者自己在 Windows 上编译和测试 DuckDB 的方式。

使用 CMake,生成一组 Visual Studio 项目文件。然后在 Visual Studio 中打开这些项目文件(我们使用 Visual Studio Community 2019),编译并运行测试套件(unittest)。可以通过将测试名称添加为命令行参数来运行单个测试。

于 2019-10-30T10:24:07.197 回答
0

DuckDB 目前似乎没有发布版本。所以不要以为创作者没有留下任何错误......

您可以添加编译器标志-fpermissive来忽略错误(例如make CXX="g++ -fpermissive")。

但是忽略这样的错误并不总是安全的。

所以我试图解决这个问题,我能够在 Windows 上构建一个版本。有关我的解决方案,请参阅https://github.com/cwida/duckdb/issues/361

于 2019-11-25T10:49:14.017 回答