【问题标题】:How do I address warnings when compiling SQLite with VC++?使用 VC++ 编译 SQLite 时如何解决警告?
【发布时间】:2011-01-16 23:02:53
【问题描述】:

每当我使用 Visual C++ 9 编译 SQLite 时,我都会收到数百条警告,例如

  • 可能未初始化的变量
  • 从更宽的整数类型到更窄的整数类型的转换
  • 有符号/无符号整数不匹配。

我并不孤单 - 有一个 SQLite FAQ question 专门针对此问题。该问题的答案表明

  • SQLite 开发人员使用的 GCC 中不会出现这些警告
  • 警告不是问题,因为团队对代码进行了彻底的测试

我当然不能反对这些观点,但是......

  • 我不使用 GCC - 我使用 VC++,而 VC++ 确实显示警告
  • 他们测试了使用 GCC 编译的代码,而我不使用 GCC,因此可能存在一些实现定义的差异,或者 GCC 和 VC++ 之间的 C 标准遵从性不同级别,这会巧妙地破坏代码并造成严重后果。

这就是为什么我不喜欢简单地忽略所有警告的想法。

那么我该如何处理 VC++ 在编译 SQLite 时显示的警告呢?

【问题讨论】:

  • “巧妙地破坏代码并造成严重后果” - SQLite 测试套件是否编译并运行?仍然不能证明相同的行为,因为差异可能会破坏代码相应的测试,但这是一个很好的指标。
  • 您收到什么警告?我刚刚尝试使用 /W4 并得到了几个应该可以安全忽略的 C4127(查看一些代码部分)和一个关于将 int 转换为“2 字节无符号整数”的 C4244。我会说你必须相信 SQLite 开发人员与后者......所以忽略警告。

标签: c++ c sqlite visual-c++ compiler-construction


【解决方案1】:

如果这些警告实际上没有造成任何伤害,为什么不使用#pragmas 来禁用它们呢?或者切换到较低的警告级别(因为我假设您将 SQLite 源作为单独的 VC lib 项目?)

【讨论】:

  • 我可以做的更简单——忽略警告。我只编译一次 SQLite,因为我从不修改它。问题是忽略它们或做其他事情是否合理。
  • #pragma 进入源代码。因为它是一个库。为什么不在 .vcproj 中修复它?后者可能是为您的项目定制的,因为 SQLite 开发人员不维护它。
  • 我通常把#pragmas 像这样放在预编译的头文件(stdafx.h)中,所以你不需要更改SQLite 源,但我使用项目文件本身是个好主意.
【解决方案2】:

使用 C++ 的开发人员如何处理警告?调查您收到警告的代码,确定警告是否告诉您需要了解的内容,然后根据需要更改代码。我不确定我是否真的理解你的问题。

也许如果您发布了一个特定的警告(带有代码),我们也许可以就您需要采取的措施向您提供建议。

【讨论】:

  • "根据需要更改代码"。除非您可以说服 SQLite 项目他们应该在 VC++ 上无警告地编译,否则他们肯定不太可能为此接受一大堆补丁。不受支持的 SQLite 分支将是一项重大任务。
  • @Steve Jessop——我没有从这个问题中得到答案。听起来他只是想消除对本地构建环境的警告。听起来他并不特别关心将他的更改回馈给世界——也许你在问题中看到了我没有看到的东西?
  • 好吧,即使你是唯一一个使用分叉的人,它也会让每次更新都比它需要的更“有趣”。我认为尖牙和“任何开发人员”之间的区别在于这不是他的代码,他可能不想修复它,管理来自上游的合并等。
【解决方案3】:

我会说,编译像 SQLite 这样复杂的东西,使用开发人员自己说他们从未使用过的编译器和库,注定要失败,或者至少会非常非常痛苦。 GCC 很容易在 Windows 上安装和使用(从 http://tdragon.net/recentgcc 获取),那么为什么不使用它呢?

【讨论】:

  • Em... 我打算将 SQLite 静态链接到我用 VC++ 编译的程序中。我想如果我使用 GCC 进行 SQLite 编译更改,我遇到的真正痛苦要高得多。
  • @sharptooth。不,只要您使用 C 接口,MinGW(适用于 Windows 的 GCC)生成的库是兼容的。
  • +1,我会听从你的建议,即使我从来没有遇到过问题。 (顺便说一句,99.0% 的警告是关于整数/双精度转换和有符号/无符号比较)
  • @jalf:我们使用 VC++ 编译的 SQLite 已经有一段时间了,没有发现任何问题。这与“工作正常”非常不同。如果它在客户处部署的副本中的某些边缘情况出现故障,我们可能会花费数周时间尝试诊断问题。
【解决方案4】:

首先,请记住警告不是错误指示。它们的存在是为了将开发人员的注意力吸引到可能表示错误的事情上,而不是其他事情。

如果代码有效,则发出的警告数量几乎无关紧要。

如果您想安全起见,请查看警告:它们是否与 VS 和 GCC 以不同方式处理的实现定义的行为有关?如果是这样,您可能会遇到问题。但只要警告是关于两个编译器处理相同的事情(例如整数/双精度转换),就可以忽略它。

我记得(自从我在 VS 上编译 SQLite 而没有静音警告以来已经有一段时间了),几乎所有警告都是关于内置类型之间的隐式转换,只要开发人员知道它们都是非常安全的正在发生。

SQLite 在 VS 上工作得很好。该库被许多大型项目广泛使用。它经过了相当广泛的测试。

【讨论】:

    【解决方案5】:

    在 VC9 解决方案资源管理器中选择文件,右键单击,选择“属性”。 然后转到C++ -> General 选项卡并将Warning level 设置为Off。 这将只关闭这些文件的所有警告。

    我使用我使用的大多数外部 lib 文件都这样做:“修复”这些文件没有任何好处(如果它们不是真正的错误),关闭警告有助于保持构建输出窗口清洁,所以我不这样做不要错过我自己代码中的警告。

    【讨论】:

    • 我做的更简单:我将它编译为一个单独的静态库,因此在我的代码编译过程中不会出现警告。
    【解决方案6】:

    这些警告的基本意思是:

    1. 如果将代码移植到所有基本类型(char、short、int、long、long long)与原始开发人员使用和测试的大小完全相同的环境中,则代码可能会按测试工作(尽管注意那些可能未初始化的变量),但是

    2. 1234563您收到这些警告的地方。即使您在两种环境中都使用 GCC,情况也是如此。请参阅C FAQ 3.19 了解可能发生的行为类型的一些示例(请记住,C 和 C++ 标准现在都强制执行“保值”规则)。

    这是草率编码的标志。他们确实应该解决导致这些警告的大多数问题(通常,在二进制运算符中混合有符号和无符号类型是有风险的,我敢打赌他们在这里做了很多)。我已经修复了过去导致此类警告的其他人的代码,使其在移植到未来环境时更加健壮。但是就是说,如果他们使用与您将使用的相同的基本类型大小进行编译和测试(如果有一个兼容的 C 语言接口可以链接到,他们几乎肯定是这样),那么您可能无需修复许多问题就可以逃脱这些问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-16
      • 2012-10-01
      • 1970-01-01
      • 2011-04-09
      • 1970-01-01
      • 2013-04-29
      • 2020-11-25
      • 1970-01-01
      相关资源
      最近更新 更多