对于我的硕士学位,我需要在一个名为 duckdb 的数据库上工作(它在 git hub 上)。通常在 Linux 上,您可以简单地克隆它并“制作”它以进行安装。
安装 CMake 和 Cygwin 后,我在 Windows 上遇到了同样的问题。
编译到一半就报错
'DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1445:96:
error: ISO C++ forbids comparison between pointer and integer [-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%] Building CXX object test/sql/capi/CMakeFiles/test_sql_capi.dir/ub_test_sql_capi.cpp.obj In file included from C:/duckdb/test/sql/capi/test_capi.cpp:1:0, from test_capi.cpp:0:
C:/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp: In instantiation of '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: required from '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: required from here C:/DB/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1445:96: error: ISO C++ forbids comparison >between pointer and integer [-fpermissive] auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return >static_cast(lhs != rhs); }
我只在路径等中编辑掉了我的用户名。
最佳答案
我不了解图书馆,所以无法给出明确的答案。我将按照 https://github.com/cwida/duckdb 处的代码进行操作.
根据错误信息,有问题的代码在test/sql/capi/test_capi.cpp
的第332行,即:
REQUIRE(stmt != NULL);
REQUIRE
是单元测试库 Catch2 中的一个宏,它执行一些魔术来解析给它的表达式。重要的是 stmt != NULL
实际上不会立即执行,而只会通过函数间接执行。
stmt
在第 324 行声明为
duckdb_prepared_statement stmt = nullptr;
和duckdb_prepared_statement
是src/include/duckdb.h
第94行的typedef:
typedef void *duckdb_prepared_statement;
因此,有问题的行的目的是检查 stmt
在一些中间操作之后是否仍然是 nullptr
。
通常 stmt != NULL
就可以了。但是,由于 Catch2 宏引入了中间函数调用而不是直接计算此表达式,因此不应用特定于文字的隐式转换。
特别是 NULL
根据标准是 std::nullptr_t
类型的纯右值或值为 0 的整数文字。这些中的哪一个(以及哪个整数类型)是实现定义的。
通常禁止比较整数和指针,但是值为零的整数文字有一个特殊的异常(exception),允许它们隐式转换为任何指针类型的空指针。如果直接计算 stmt != NULL
,就会发生这种情况。
但是由于 Catch2 的插入,NULL
首先被传递,然后通过变量与 stmt
进行比较,这使得特殊的零文字规则不再适用.因此,如果 NULL
在当前实现中是整数文字,则通过 REQUIRE
将 stmt
与 NULL
进行比较将失败。
Catch2 确实考虑了这个问题,并且在 third_party/catch/catch.hpp
中为 compareNotEqual
重载了处理 NULL
的情况> 是 int
或 long
类型的零整数文字,但出于某种原因,未考虑 long long
的情况。我不知道这是否是 Catch2 的问题,还是仅存在于 duckdb 中包含的克隆版本中。
因此,如果实现对 NULL
使用类型为 long long
的零文字,则会发生您观察到的错误。
真正的 duckdb 应该使用 nullptr
而不是 NULL
(就像它在初始化时所做的那样),它没有这些问题并且因为这些而被添加到语言中问题。
我想您可以简单地尝试通过将 NULL
替换为 nullptr
来解决此问题(也许在其他测试用例中也是如此)。
然而,有问题的代码仅出现在文件中,这些文件本身就是实际库代码的单元测试。因此,cmake 或 make 应该有一些选项将禁止构建单元测试,这样您就可以忽略这个特定错误,希望它也不会出现在实际库代码中的任何地方。
如果我的评估是正确的,您可能需要考虑使用 duckdb 提交错误报告,假设他们首先支持您的平台。
关于c++ - 使用 cmake 在 Windows 上编译 C++ 数据库时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58486414/