-Werror 导致编译器在 #warning 时停止。我可以做什么来防止这种情况发生?

发布于 2024-10-06 11:50:58 字数 596 浏览 8 评论 0原文

首先,我希望它在收到警告时停止。但我也想打印出一些信息性消息(例如“回来实施这个!”)。

不幸的是,我的编译器不支持 #info#message#pragma message() 等。

我知道有 - Wno-error=,但我的 google-foo 很弱,我似乎找不到 #warning.我尝试过 -Wno-error=warning,但那只是说“没有 -Wwarning”。与“警告”相同。

有什么建议吗?

就其价值而言,我正在使用 Tensilica Xtensa 编译器 xt-xcc,它出现成为 GNU 衍生产品,或者至少使用 GNU 前端。它的版本是8.0.0。

First off, I want it to stop on warnings. But I also want to print out some informative messages (like "Come back and implement this!").

Unfortunately, my compiler doesn't support #info, #message, #pragma message(), etc.

I know there's -Wno-error=<something>, but my google-foo is weak, and I can't seem to find out the <something> for #warning. I've tried -Wno-error=warning, and that just says "there's no -Wwarning". Same with "warn".

Any suggestions?

For what its worth, I'm using the Tensilica Xtensa compiler, xt-xcc, which appears to be a GNU derivative, or at least uses the GNU front end. It's version 8.0.0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

儭儭莪哋寶赑 2024-10-13 11:50:58

我不熟悉 Tensilica Xtensa 编译器 (xt-xcc),但使用标准 GCC,您可以使用

  #pragma GCC diagnostic warning "-Wcpp"

#warning 发出简单的警告(不是错误,因为-Werror)。要使效果暂时有效,您可以在 #pragma GCC 诊断推送#pragma GCC 之间使用此 #pragma#warning诊断弹出

当我使用 GCC 4.6.1(命令 gcc -c -Werror warning-test.c)编译包含以下内容的文件时

    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcpp"
    #warning one
    #pragma GCC diagnostic pop

    #warning two

,我得到以下输出:

```lang-none
warning-test.c:3:2: warning: #warning one [-Wcpp]
warning-test.c:6:2: error: #warning two [-Werror=cpp]
cc1: all warnings being treated as errors
```

当我删除第二个 #warning 时,编译不会因错误而中断。

您还可以将 -Werror 编译器选项替换为 -Werror -Wno-error=cpp。我不知道 cpp 警告类别还包括哪些其他影响(并且您可能在其他地方有一个合法的 #warning ,您希望将其捕获为错误),所以暂时禁用特定#warning的错误并立即恢复设置似乎是满足您的要求的更准确的方法。

使用 GCC 版本 4.8.4 和 4.9.2 提供几乎相同的行为(仅额外打印出源代码行)。但使用 GCC 版本 5.0.1(预发布版本包含在 Ubuntu 15.04< /a> (Vivid Vervet)) 将给出两个警告,除非也包含选项 -Werror=cpp 。因此,似乎较新的 GCC 中的 -Werror 不再像以前那样暗示 -Werror=cpp ,并且如果需要,需要单独提供。

I am not familiar with the Tensilica Xtensa compiler (xt-xcc), but with standard GCC you can use

  #pragma GCC diagnostic warning "-Wcpp"

to make #warning a matter of simple warning (not an error because of -Werror). To make the effect temporary, you can embrace this #pragma and the #warning between #pragma GCC diagnostic push and #pragma GCC diagnostic pop.

When I compile a file containing the following

    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcpp"
    #warning one
    #pragma GCC diagnostic pop

    #warning two

with -Werror using GCC 4.6.1 (command gcc -c -Werror warning-test.c), I get the following output:

```lang-none
warning-test.c:3:2: warning: #warning one [-Wcpp]
warning-test.c:6:2: error: #warning two [-Werror=cpp]
cc1: all warnings being treated as errors
```

When I remove the second #warning, the compilation is not interrupted by an error.

You can also replace your -Werror compiler options with -Werror -Wno-error=cpp. I am not aware what other effects the cpp category of warnings include (and you might have a legitimate #warning in some other place that you want to catch as error), so temporarily disabling the error for a specific #warning and restoring the settings immediately after seems more accurate method of meeting your requirements.

Using GCC versions 4.8.4 and 4.9.2 gives pretty much the same behavior (only the source line is printed out additionally). But using GCC version 5.0.1 (prerelease version included in Ubuntu 15.04 (Vivid Vervet)) will give two warnings unless option -Werror=cpp is included as well. So it seems that -Werror with a newer GCC does not anymore imply -Werror=cpp like before and it needs to be provided separately if desired.

醉生梦死 2024-10-13 11:50:58

十年后,发出警告并避免来自 -Wpedantic 的这些额外消息/错误的正确方法是使用 #pragma message。 GCC 至少从 GCC 4.5 和 Clang 至少自 Clang 6

这些编译器的现代版本甚至支持 #pragma GCC 错误“消息”#pragma GCC 警告“消息” (GCC 9,已在 Clang 6 中支持)。

Ten years later, the proper way to issue warnings and avoid these additional messages/errors from -Wpedantic is to use #pragma message. GCC supports this syntax since at least GCC 4.5, and Clang since at least Clang 6.

Modern versions of these compilers even support #pragma GCC error "message" and #pragma GCC warning "message" (GCC 9, already supported in Clang 6).

谁把谁当真 2024-10-13 11:50:58

问题所在:

#warning "Come back and implement this"
#warning "Do not do that!"
#warning "Must fix this before release"

通常,编译器会在错误或警告消息中包含 - 的参数或 - #warning 之后的材料。

而且,通常情况下,如果编译器检测到需要警告的内容,它会相当清楚地报告它。


考虑到这些要求,我认为处理这个问题的唯一方法是保护 #warning 指令...

#ifdef DO_WARNINGS
#warning "Some warning"
#endif /* DO_WARNINGS */

大多数时候,您在编译时不使用 -DDO_WARNINGS;当您需要检查#warning警告(使用-Werror)时,那么您毕竟要包含-DDO_WARNINGS,接受编译将失败。请记住,即使存在个别编译错误,make -k 也会尽可能多地执行操作。


GCC 4.4.1 手册第 5.52.9 节(部分)说:

5.52.9 诊断指令

GCC 允许用户有选择地启用或禁用某些类型的诊断,并更改
诊断的类型。例如,项目的政策可能要求所有来源
使用“-Werror”进行编译,但某些文件可能有例外,允许特定类型
警告。或者,项目可能有选择地启用诊断并将其视为错误,具体取决于
定义了预处理器宏。

#pragma GCC 诊断类型选项

修改诊断的处理。请注意,并非所有诊断都可以修改;
目前只能显示警告(通常由“-W...”控制)
受控制,而且不是全部。使用“-fdiagnostics-show-option”来确定
哪些诊断是可控的以及哪些选项控制它们。
kind 是“错误”,将此诊断视为错误,“警告”将其视为
警告(即使“-Werror”有效),或者如果诊断是“忽略”
被忽略。 option 是一个双引号字符串,与命令行匹配
选项。

#pragma GCC 诊断警告“-Wformat”
#pragma GCC 诊断错误“-Wformat”
#pragma GCC 诊断忽略“-Wformat”

请注意,这些编译指示会覆盖所有命令行选项。另外,虽然它
将这些编译指示放在源代码中的任何位置在语法上都是有效的,唯一的
它们受支持的位置是在定义任何数据或函数之前。正在做
否则可能会导致不可预测的结果,具体取决于优化器的方式
管理您的来源。如果多次列出同一选项,则最后一个选项
指定的一项即为有效的一项。该编译指示并非旨在成为
命令行选项的通用替代品,但用于实现
严格把控项目政策。

GCC 还提供了一种在编译期间打印消息的简单机制。

#pragma 消息字符串

在编译时将字符串打印为编译器消息。该消息仅供参考
只是,既不是编译警告也不是错误。

#pragma message "正在编译" __FILE__ "..."

字符串可以带括号,并打印位置信息。

我不确定您是否愿意将 #warning 行编辑为 #pragma message 行。它可以帮助您解决问题 - 并且只会比在 #warning 周围添加条件编译更糟糕,因为 #pragma message 可能会受到较少编译器的支持。这取决于您的可移植性要求。

What's wrong with:

#warning "Come back and implement this"
#warning "Do not do that!"
#warning "Must fix this before release"

Normally, the compiler will include the argument(s) to - or material after - #warning in the error or warning message.

And, normally, if the compiler detects something that warrants a warning, it reports it fairly clearly.


Given the requirements, I think the only way to deal with this is to protect the #warning directives...

#ifdef DO_WARNINGS
#warning "Some warning"
#endif /* DO_WARNINGS */

Most of the time, you compile without -DDO_WARNINGS; when you need to check on the #warning warnings (with -Werror), then you include -DDO_WARNINGS after all, accepting that the compilation will fail. Remember that make -k will do as much as possible even in the presence of individual compilation errors.


Section 5.52.9 of the GCC 4.4.1 manual says (in part):

5.52.9 Diagnostic Pragmas

GCC allows the user to selectively enable or disable certain types of diagnostics, and change
the kind of the diagnostic. For example, a project’s policy might require that all sources
compile with ‘-Werror’ but certain files might have exceptions allowing specific types of
warnings. Or, a project might selectively enable diagnostics and treat them as errors depending
on which preprocessor macros are defined.

#pragma GCC diagnostic kind option

Modifies the disposition of a diagnostic. Note that not all diagnostics are modifiable;
at the moment only warnings (normally controlled by ‘-W...’) can be
controlled, and not all of them. Use ‘-fdiagnostics-show-option’ to determine
which diagnostics are controllable and which option controls them.
kind is ‘error’ to treat this diagnostic as an error, ‘warning’ to treat it like
a warning (even if ‘-Werror’ is in effect), or ‘ignored’ if the diagnostic is to
be ignored. option is a double quoted string which matches the command line
option.

#pragma GCC diagnostic warning "-Wformat"
#pragma GCC diagnostic error "-Wformat"
#pragma GCC diagnostic ignored "-Wformat"

Note that these pragmas override any command line options. Also, while it
is syntactically valid to put these pragmas anywhere in your sources, the only
supported location for them is before any data or functions are defined. Doing
otherwise may result in unpredictable results depending on how the optimizer
manages your sources. If the same option is listed multiple times, the last
one specified is the one that is in effect. This pragma is not intended to be a
general purpose replacement for command line options, but for implementing
strict control over project policies.

GCC also offers a simple mechanism for printing messages during compilation.

#pragma message string

Prints string as a compiler message on compilation. The message is informational
only, and is neither a compilation warning nor an error.

#pragma message "Compiling " __FILE__ "..."

string may be parenthesized, and is printed with location information.

I'm not sure whether you feel like editing your #warning lines into #pragma message lines. It would get you around the problem - and is only worse than adding conditional compilation around the #warning in that #pragma message might be supported by fewer compilers. It depends on what your portability requirements are.

柠檬色的秋千 2024-10-13 11:50:58

鉴于 #warning 可能由预处理器处理,您可以单独运行预处理器而不使用 -Werror,然后运行编译器,并在预处理器输出上禁止预处理。

为此,通过预处理器使用除 -Werror 之外的所有正常选项运行 .c 文件,并将输出生成为 .i 文件(对于 C++ 为 .ii)。编译器将这些文件识别为不进行预处理,因此您可以使用 -Werror 编译它们,并假设预处理器删除 #warning 并且编译器本身不处理它,这可能会解决您的问题。

我还没有测试过这个;当我遇到同样的问题时,我只是选择忍受它而不是使用 -Werror。解决方案似乎比问题更复杂!

Given that #warning is presumably processed by the pre-processor, you could run the pre-processor separately without -Werror, then run the compiler with pre-processing inhibited on the pro-processor output.

To do this run the .c file through the preprocessor with all the normal options except -Werror, and generate the output as a .i file (.ii for C++). The compiler recognises these files as not to be pre-processed so you can compile them with -Werror, and assuming that the pre-processor drops the #warning and it is not processed by the compiler itself, this may resolve your problem.

I have not tested this; when I encountered the same problem I just chose to live with it and not use -Werror. The solution seemed more complex than the problem!

浴红衣 2024-10-13 11:50:58

不幸的是,我的特定工具链没有答案,Tensilica 的工程师是这么说的。他们不支持 #message 或 #pragma message(),也不知道如何在存在 -Werror

GCC 工具链允许使用 -Wno-error=[code] 来表示“此警告不是错误”,但我还没有找到与 #warning 对应的任何代码的列表采取(甚至可能是代码列表)。

我可能会尝试找时间深入研究标准 GCC 命令行和预处理器源代码,以尝试找到 -Wno-error= 可以等于的列表,或者是否存在 -Werror= 代码对应于#warning。

Unfortunately, there is no answer for my specific toolchain, or so says the engineers at Tensilica. They don't support #message, or #pragma message(), or know of how to suppress #warning as error in the presence of -Werror.

The GCC toolchain allows the use of -Wno-error=[code] to say "this warning is not an error", but I haven't found a list that corresponds #warning to any code this would take (or even a list of codes this could be).

I may try to find the time to delve into the standard GCC command lines and pre-processor source code to try to find a list of what -Wno-error= can be equal to, or whether or not there's a -Werror= code that corresponds to #warning.

风渺 2024-10-13 11:50:58

如果您的编译器支持它,您可以尝试使用 constructor 函数属性 定义一个在程序启动时运行的函数(在 main 之前),该函数将消息打印到 stdout:

#define TOKENPASTE(x, y) TOKENPASTE2(x, y)
#define TOKENPASTE2(x, y) x ## y
#define WARNING(message) \
  static void TOKENPASTE(_print_warning, __LINE__)() __attribute__((constructor)); \
  static void TOKENPASTE(_print_warning, __LINE__)() \
  { \
    puts(message); \
  }

WARNING("fix this before ship")  // prints out a message at runtime before main

这会导致消息在运行时而不是编译时打印,这几乎一样好,特别是如果您没有其他选择。唯一的限制是您必须在函数定义之外的全局范围内使用它。

If your compiler supports it, you can try using the constructor function attribute to define a function that runs at program start (before main) that prints out a message to stdout:

#define TOKENPASTE(x, y) TOKENPASTE2(x, y)
#define TOKENPASTE2(x, y) x ## y
#define WARNING(message) \
  static void TOKENPASTE(_print_warning, __LINE__)() __attribute__((constructor)); \
  static void TOKENPASTE(_print_warning, __LINE__)() \
  { \
    puts(message); \
  }

WARNING("fix this before ship")  // prints out a message at runtime before main

This causes a message to be printed out at runtime instead of compile-time, which is almost as good, especially if you have no other options. The only restriction is that you have to use this at global scope outside of a function definition.

与风相奔跑 2024-10-13 11:50:58

-Wno-error=#warnings 似乎适用于最近的 clang(测试 14..17)

G++(11 和 12)不支持等效项,建议使用 --no-warnings - 这不是你想要的。

唯一的问题可能是让构建工具消化哈希,因此它会传递给编译器......

-Wno-error=#warnings seem to work with recent clangs (tested 14..17)

G++ (11 & 12) does not support the equivalent and suggest using --no-warnings - which is not what you want.

The only issue might be to get the hash digested by your build tool, so it goes to the compiler...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文