Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C -Werror导致编译器在#警告时停止。我能做些什么来防止这种情况?_C_Gcc_Embedded_C Preprocessor_Preprocessor Directive - Fatal编程技术网

C -Werror导致编译器在#警告时停止。我能做些什么来防止这种情况?

C -Werror导致编译器在#警告时停止。我能做些什么来防止这种情况?,c,gcc,embedded,c-preprocessor,preprocessor-directive,C,Gcc,Embedded,C Preprocessor,Preprocessor Directive,首先,我希望它在收到警告时停止。但是我还想打印一些信息性的消息(比如“回来实现这个!”) 不幸的是,我的编译器不支持#info、#message、#pragma message()等 我知道有-Wno error=,但是我的google foo很弱,而且我似乎无法找到#warning的。我试过-Wno error=warning,它只是说“没有-Wwarning”。与“警告”相同 有什么建议吗 不管它值多少钱,我使用的是Tensilica xtensa编译器xt xcc,它似乎是gnu的派生版本

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

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

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

有什么建议吗


不管它值多少钱,我使用的是Tensilica xtensa编译器xt xcc,它似乎是gnu的派生版本,或者至少使用gnu前端。它是8.0.0版。

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

#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
这会导致消息在运行时而不是编译时打印出来,这几乎同样好,尤其是在没有其他选项的情况下。唯一的限制是您必须在函数定义之外的全局范围内使用它。

有什么问题:

#warning "Come back and implement this"
#warning "Do not do that!"
#warning "Must fix this before release"
通常情况下,编译器会在错误或警告消息中包含警告后的参数或材料

而且,通常情况下,如果编译器检测到一些值得警告的东西,它会非常清楚地报告它


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

#ifdef DO_WARNINGS
#warning "Some warning"
#endif /* DO_WARNINGS */
大多数情况下,您在编译时不会出现
-DDO_警告
;当您需要检查
#警告
警告时(使用
-Werror
),那么您毕竟包括
-DDO_警告
,接受编译将失败。请记住,
make-k
将尽可能多地执行操作,即使存在个别编译错误


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

5.52.9诊断性杂注 GCC允许用户有选择地启用或禁用某些类型的诊断,并进行更改 诊断的类型。例如,项目的策略可能要求所有源 使用'-Werror'编译,但某些文件可能有允许特定类型的 警告。或者,项目可能有选择地启用诊断,并视情况将其视为错误 在其上定义预处理器宏

#pragma GCC diagnostic kind option
修改诊断的配置。注意,并非所有诊断都是可修改的; 目前只能显示警告(通常由“-W…”控制) 受控制,而不是全部。使用“-fddiagnostics show option”确定 哪些诊断是可控的,哪些选项控制它们。 “种类”是“错误”,将此诊断视为错误,“警告”是将其视为错误 警告(即使'-Werror'生效),或在诊断失败时“忽略” 被忽视。选项是与命令行匹配的双引号字符串 选择权

#pragma GCC diagnostic warning "-Wformat"
#pragma GCC diagnostic error "-Wformat"
#pragma GCC diagnostic ignored "-Wformat"
请注意,这些杂注覆盖所有命令行选项。还有,当它 在语法上,将这些pragma放在源代码中的任何位置都是有效的 支持的位置是在定义任何数据或函数之前。做 否则可能会导致不可预测的结果,具体取决于优化器的工作方式 管理你的资源。如果同一选项多次列出,则最后一个选项 指定的一个是有效的一个。此pragma不打算成为 命令行选项的通用替换,但用于实现 严格控制项目政策

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

#pragma message string
在编译时将字符串作为编译器消息打印。这条消息是信息性的 仅,并且既不是编译警告也不是错误

#pragma message "Compiling " __FILE__ "..."
字符串可以用括号括起来,并打印位置信息


我不确定您是否想将
#警告
行编辑为
#pragma消息
行。它可以帮助您解决这个问题,而且比在
#warning
周围添加条件编译更糟糕,因为
#pragma消息
可能会被更少的编译器支持。这取决于您的可移植性要求。

不幸的是,我的特定工具链没有答案,或者Tensilica的工程师如是说。他们不支持#message或#pramga message(),也不知道如何在-Werror出现时将#警告作为错误进行抑制

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

我可能会找时间深入研究标准GCC命令行和预处理器源代码,试图找到-Wno error=可以等于什么的列表,或者是否有一个-Werror=代码对应于#警告。如果我这样做,我会回来更新答案。

鉴于#警告可能是由预处理器处理的,您可以单独运行预处理器而不使用-Werror,然后在预处理器输出上禁用预处理的情况下运行编译器

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

我没有测试过这个;当我遇到同样的问题时,我只是选择接受它,而不是使用-Werror。解决方案似乎比问题更复杂<
  #pragma GCC diagnostic warning "-Wcpp"
    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcpp"
    #warning one
    #pragma GCC diagnostic pop

    #warning two
    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