首先,我希望它在警告时停止。但我也想打印出一些信息性的消息(比如“回来实现这个!“).
不幸的是,我的编译器不支持#info
,#message
,#pragma message()
等。
我知道有-Wno-error=<something>
,但我的google-foo很弱,我似乎找不到#warning
的<something>
。我试过-Wno-error=warning
,它只是说“没有-Wwarning
”。与“warn
”相同。
有什么建议吗?
就其价值而言,我使用的是Tensilica Xtensa编译器xt-xcc,它似乎是GNU的衍生物,或者至少使用了GNU的前端。版本是8.0.0。
7条答案
按热度按时间klsxnrf11#
我不熟悉Tensilica Xtensa编译器(
xt-xcc
),但可以使用标准GCC使
#warning
成为一个简单的警告(而不是因为-Werror
而产生的错误)。为了使效果暂时,您可以包含这个#pragma
和#pragma GCC diagnostic push
和#pragma GCC diagnostic pop
之间的#warning
。当我编译包含以下内容的文件时
使用
-Werror
使用GCC 4.6.1(命令gcc -c -Werror warning-test.c
),我得到以下输出:wbgh16ku2#
十年后,发出警告并避免这些来自-Wpedantic的额外消息/错误的正确方法是使用
#pragma message
。GCC至少从GCC 4.5开始支持此语法,并且至少从Clang 6开始支持Clang。这些编译器的现代版本甚至支持
#pragma GCC error "message"
和#pragma GCC warning "message"
(GCC 9,在Clang 6中已经支持)。mefy6pfw3#
有什么不好的:
通常情况下,编译器会在错误或警告消息中包含-
#warning
的参数或-#warning
之后的材料。而且,通常情况下,如果编译器检测到需要警告的内容,它会相当清楚地报告它。
考虑到这些要求,我认为处理这个问题的唯一方法是保护
#warning
指令。大多数情况下,编译时不使用
-DDO_WARNINGS
;当你需要检查#warning
警告(使用-Werror
)时,那么你最终还是包括了-DDO_WARNINGS
,接受编译将失败的事实。请记住,即使存在个别编译错误,make -k
也会尽可能地执行。GCC 4.4.1手册的第5.52.9节(部分)指出:
5.52.9诊断pragma
GCC允许用户选择性地启用或禁用某些类型的诊断,并更改诊断的种类。例如,项目的策略可能要求所有源代码都使用“-Werror”编译,但某些文件可能有允许特定类型警告的例外。或者,项目可能有选择地启用诊断,并根据定义的预处理器宏将其视为错误。
修改诊断程序的处置。请注意,并非所有诊断都是可修改的;此时,只有警告(通常由“-W…”控制)可以被控制,而不是所有的警告。使用“-fdiagnostics-show-option”确定哪些诊断程序是可控的,以及哪个选项控制它们。kind是'error'将此诊断视为错误,'warning'将其视为警告(即使'-Werror'有效),或'ignored'如果诊断将被忽略。option是与命令行选项匹配的双引号字符串。
请注意,这些杂注会覆盖任何命令行选项。此外,虽然将这些杂注放在源代码中的任何位置在语法上都是有效的,但它们唯一受支持的位置是在定义任何数据或函数之前。否则可能会导致不可预知的结果,具体取决于优化器管理源的方式。如果多次列出相同的选项,则最后指定的选项将有效。此杂注不打算作为命令行选项的通用替代品,而是用于实现对项目策略的严格控制。
GCC还提供了一种简单的机制,用于在编译期间打印消息。
在编译时将字符串打印为编译器消息。该消息仅供参考,既不是编译警告,也不是错误。
字符串可以用括号括起来,并打印出位置信息。
我不确定您是否愿意将
#warning
行编辑为#pragma message
行。它可以解决这个问题,而且只比在#warning
周围添加条件编译更糟糕,因为#pragma message
可能由更少的编译器支持。这取决于您的可移植性要求是什么。1bqhqjot4#
假设#warning是由预处理器处理的,你可以单独运行预处理器而不使用-Werror,然后在pro-processor输出上禁止预处理的情况下运行编译器。
为此,使用除-Werror之外的所有常规选项通过预处理器运行.c文件,并将输出生成为.i文件(C++为.ii)。编译器会将这些文件识别为 not to be pre-processed,因此您可以使用-Werror编译它们,并且假设预处理器丢弃了#警告并且编译器本身没有处理它,这可能会解决您的问题。
我没有测试过这个;当我遇到同样的问题时,我只是选择接受它,而不使用-Werror。解决方案似乎比问题更复杂!
qyzbxkaa5#
不幸的是,我的特定工具链没有答案,Tensilica的工程师说。它们不支持#message或#pragma message(),也不知道如何在出现-Werror时将#warning作为error禁止。
GCC工具链允许使用-Wno-error=[code]来表示“this warning is not an error”,但我还没有找到一个列表,将#warning对应于任何可能的代码(甚至是可能的代码列表)。
我可能会找时间深入研究标准GCC命令行和预处理器源代码,试图找到一个列表,列出-Wno-error=可以等于什么,或者是否有一个-Werror=代码对应于#warning。
gstyhher6#
如果你的编译器支持它,你可以尝试使用
constructor
function属性来定义一个在程序开始时(在main
之前)运行的函数,该函数将一条消息打印到stdout:这会导致在运行时而不是编译时打印出消息,这几乎是一样好的,特别是如果你没有其他选择的话。唯一的限制是你必须在函数定义之外的全局范围内使用它。
yzuktlbb7#
-Wno-error=#warnings
似乎可以处理最近的clangs(测试14..17)G++(11 & 12)不支持等价的,建议使用
--no-warnings
-这不是你想要的。唯一的问题可能是让你的构建工具消化散列,所以它会进入编译器……