【问题标题】:GCC force warning to be an error: excess elements in array initializerGCC 强制警告为错误:数组初始值设定项中的多余元素
【发布时间】:2016-03-09 08:02:09
【问题描述】:

我的项目必须使用两种不同的编译器进行编译。一个创建 DLL(用于 PC 模拟,Mingw32-gcc-4.7.2),另一个创建 ELF(用于真实硬件)。两种编译器都有部分不同的行为,但我们希望它们尽可能相似,至少在错误方面是这样。 我想在 GCC 中激活一个特定错误,这只是一个警告:

warning: excess elements in array initializer [enabled by default]

有没有办法只将此警告升级为错误?我只找到了激活一组警告的解决方案,而不仅仅是这个。如果我没记错的话,组标志应该在括号中的警告消息后面:[默认启用] ...我不希望所有默认警告都作为错误。

编辑:使用“-Werror=XXX”使其成为活动错误的标志是什么

【问题讨论】:

  • 如果你看到例如this GCC online manual about warning flags,您会很早就看到-Werror=,您可以在其中告诉 GCC 将特定警告转换为错误。
  • 我已经看到了 -Werror= 功能。但我认为它只能切换由一个标志控制的一组警告(在警告后放入[]-括号,如:-Werror=undef for "XXX is not defined [-Wundef]")。但是如何将我的特定警告切换为错误?
  • 虽然我不知道“多余元素”警告使用什么警告选项,但您可以通过执行 -Werror=undef(对于 -Wundef 警告选项)将单个警告变成错误。
  • 即使在 GCC 5.3.0 中,似乎也没有一个独立的选项可以将该警告变为错误。看起来你必须编写好的 C 并确保没有警告,所以你可以使用-Werror。或者您必须搜索构建日志才能找到该警告。我试过-std=c11 -pedantic -Wall -Wextra,即使这样似乎也没有触发错误——仍然只是一个警告。这仍然符合标准;发出诊断(警告)——其他情况由实现定义。
  • 标准的相关章节是ISO/IEC 9899:2011 §6.7.9 Initialization。第一个约束是:任何初始化程序都不得尝试为未包含在正在初始化的实体中的对象提供值。 数组的初始化程序过多违反了该约束。如果您遇到无法计算初始化程序的问题,您需要学习如何做到这一点。如果您的同事不会数,那么您需要培训他们。如果您的代码生成器无法计数,请修复代码生成器。这种情况应该很少发生——应该被开发者发现。

标签: gcc compiler-errors gcc-warning gcc4.7


【解决方案1】:

tl;dr

-pedantic-errors 似乎有效。

https://godbolt.org/z/BD2XTr

搜索路径

我也有同样的需求,但一直没有找到答案。当我发现这个问题还没有答案时,我决定深入研究 GCC 源代码。

一个简单的git grep 'excess elements in array initializer'告诉我警告是从gcc/c/c-typeck.c中的pedwarn_init()生成的。

函数在同一文件的6375 行定义。

/* Issue a pedantic warning for a bad initializer component.  OPT is
   the option OPT_* (from options.h) controlling this warning or 0 if
   it is unconditionally given.  GMSGID identifies the message.  The
   component name is taken from the spelling stack.  */

static void ATTRIBUTE_GCC_DIAG (3,0)
pedwarn_init (location_t loc, int opt, const char *gmsgid, ...)
{
  /* Use the location where a macro was expanded rather than where
     it was defined to make sure macros defined in system headers
     but used incorrectly elsewhere are diagnosed.  */
  location_t exploc = expansion_point_location_if_in_system_header (loc);
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool warned = emit_diagnostic_valist (DK_PEDWARN, exploc, opt, gmsgid, &ap);
  va_end (ap);
  char *ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
  if (*ofwhat && warned)
    inform (exploc, "(near initialization for %qs)", ofwhat);
}

调用者将0 传递为OPT。所以我认为没有办法把这个警告变成一个错误。但我注意到函数中使用了DK_PEDWARNDK_PEDWARN 是这样定义的,

DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn", NULL)

但是没有-Wpedwarn。不过我知道有-pedantic。所以以防万一我在 GCC 信息中搜索了pedantic,瞧,它在第 2.1 节中。 (强调我的)

2.1 C语言

[...] 要在 GCC 中选择此标准,请使用以下选项之一 '-ansi'、'-std=c90' 或 '-std=iso9899:1990';获得所有 标准要求的诊断,您还应该指定 '-pedantic' (或 '-pedantic-errors' 如果你想让它们成为错误 而不是警告)。 *注意控制 C 方言的选项:C 方言选项。

它将所有迂腐警告转换为错误,但我认为它比 -Werror 更好。

【讨论】:

    猜你喜欢
    • 2016-08-10
    • 1970-01-01
    • 2012-11-13
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多