【问题标题】:Why does clang complain about using variable-length arrays with '-std=c99' flag?为什么 clang 抱怨使用带有 '-std=c99' 标志的可变长度数组?
【发布时间】:2020-09-01 15:47:59
【问题描述】:

当我编译这个实验代码时:

int main(void)
{
    int foo = 5;
    char bar[foo];
}

使用 clang 和 '-Weverything' 或单独的 '-Wvla' 标志与 '-std=c99' 标志相结合, 我仍然收到警告:

警告:使用了可变长度数组 [-Wvla]

Example here

虽然符合 C99 的实现,但与后来的 C 标准(C11、C18 等)相比,VLA 支持是可选的,但无一例外地支持可变长度数组。


  • 为什么在 clang 中使用带有 '-std=c99' 标志的 VLA 时仍会收到此警告?
  • 这是一个错误,还是只是为了提示注意遵守后续 C 标准(以及 C89/C90)的实现?

【问题讨论】:

  • 对于那些可能不知道的人,您可以通过以下方式关闭此警告:-Wno-vla
  • gcc 在 C99 / C11 模式下不会抱怨。听起来像一个错误。
  • @FiddlingBits 是的,我知道。不过非常感谢。
  • -Weverything 旨在成为 clang 的内部测试工具;不仅仅是一个更好的“-Wall”; llvm 建议不要使用它。 (lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20181203/…)
  • 符合标准的编译器可以警告任何他们喜欢的东西。另请参阅多字符常量(如 'ABCD')和三元组。

标签: c clang c99 compiler-flags


【解决方案1】:

您是正确的,符合 C99 的实现必须支持 VLA,而实现可以符合后来的 C 标准而不支持 VLA。但我认为你只见树木不见森林:我认为上述标准之间的差异正是警告的重点。这并不是说您现在正在构建的代码可能会损坏。相反,它警告您所依赖的功能并非普遍向前兼容,因此如果您尝试在其他地方构建代码,它可能会中断。

如果 Clang 认为 VLA 是 C99 的非标准扩展,那么它根本不应该在 -std=c99 模式下接受您使用 VLA 的代码。

【讨论】:

    【解决方案2】:

    符合 C99 的实现必须支持 VLA,但使用 -Weverything 启用所有警告意味着请编译器告诉我任何可能造成问题的事情。潜在的问题包括许多符合要求的结构:

    • VLA 可能会给不完全符合的实现带来可移植性问题,其中有不少。使用-Wno-vla 禁用此警告。
    • 某些运算符组合可能是由程序员错误或对相对优先级的混淆引起的,这有时是违反直觉的。该表达式仍然符合 C 标准,但编译器会发出警告,程序员可以添加括号来防止警告。
    • 测试表达式中的赋值是一致的表达式,但编译器会发出警告,因为它们可能是简单的拼写错误,其中== 被拼写为=
    • 未使用的变量不是错误,但会在-Weverything下产生警告

    名单还在继续。如果您要求更多警告(在大多数情况下可以挽救生命),您可能需要优化您的 CFLAGS 以禁用某些选定的警告,例如 -Wno-vla,以便在您确实有意使用 VLA 时编译您的程序。

    【讨论】:

      【解决方案3】:

      人们可能希望避免在程序中使用可变长度数组的原因有很多,即使它们保证在您使用的语言版本中得到支持。一个,正如 John Bollinger 所提到的,如果您想保持与其他不支持它们的标准的兼容性。

      另一个是,在典型的基于堆栈的实现中,它们消耗的堆栈量在编译时可能不知道,或者不受信任的用户可能会影响,并且这样的实现通常没有好的检测堆栈溢出或从堆栈溢出中恢复的方法。例如,Linux 内核开发人员因此决定不应在内核中使用 VLA,using -Wvla 帮助他们执行此操作。

      这些问题肯定不会适用于每个程序,这就是为什么-Wvla 选项是一个选项;无论出于何种原因,如果您想了解程序中 VLA 的使用,您可以将其打开,如果您不这样做,您可以将其关闭。您选择使用-Weverything,它会打开所有存在的警告。这个标志并不是真的打算对程序员有用,因为正如您所注意到的,它会打开许多​​警告,这些警告仅在某些情况下对知道他们想要它们的人有用。它的目的是帮助调试编译器本身。

      实际上,您已经告诉编译器“发出所有可以发出的警告,即使它们与我的情况无关”,现在您要问为什么收到与您的情况无关的警告情况:-)

      【讨论】:

      • 虽然所有答案都非常好,我非常感谢每一个答案,但我选择这个答案作为最有帮助的答案,因为它实际上为我提供了一些新的信息和一个新的观点和一个很好的理由这个警告还是会发生。
      猜你喜欢
      • 2017-01-17
      • 2011-04-21
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 2012-01-29
      相关资源
      最近更新 更多