ARM编译器以警告(warning)和错误(error)的形式来提供编译诊断信息,并且用户可以通过一些命令行选项,来控制这些warnings和errors的打开或者关闭。编译器会在程序编译和链接过程中将遇到的warnings和errors在控制终端打印出来,如果用户有多个源代码文件,当errors被发现时,编译器只会报告第一个源文件的诊断信息。
目录
1 armclang诊断信息的格式
2 armclang常用的控制诊断消息的选项
3 使用示例
4 使用 pragma控制诊断信息
5 armasm 和 armlink的消息格式
6 armasm, armlink, armar, fromelf等工具控制诊断消息选项
--brief_diagnostics
--diag_error=[,]...
--diag_remark=[,]...
--diag_style=arm|ide|gnu
--diag_suppress=[,]...
--diag_warning=[,]...
--errors=
--remarks
7 参考文章
1 armclang诊断信息的格式
armclang遇到warning或者error时,其诊断信息的格式如下
:<file>:<line>:<col>: <type>: <message>
<file>
:出现error 或者 warning 的源文件名字<line> :
出现error 或者 warning时的行号<col> :
出现error 或者 warning时的列号<type> : 消息类型,比如可以为:
error 或者 warning<message> : 具体的消息详情,
该文本可能以-W<flag>形式的诊断标志结束,例如-Wvla-extension,用来标识error 或者 warning。只有可以抑制(suppress)的消息才具有关联标志。无法抑制的错误没有关联标志。
比如下面的warning消息示例:
file.c:8:7: warning: variable length arrays are a C99 feature [-Wvla-extension]
int i[n];
^
该warning信息会告诉用户:
警告发生在file.c文件的第8行第7列开始的地方,警告是关于 i[n] 的,即在声明数组是,使用变量作为数组的长度,这个做法在当前编译器看来是个警告。在消息的最后也告诉了用户控制这个waring的flag是 vla-extension ,是因为用了[-Wvla-extension] 编译选项才打开该flag的warning信息,所以如果想要禁止此类行为产生waring消息,可以使用[-Wno-vla-extension] 选项。
2 armclang常用的控制诊断消息的选项
Option | Description |
---|---|
-Werror | 将所有警告转换为错误。 |
-Werror=<flag> | 将警告标志<flag>变为错误。 |
-Wno-error=<flag> | 即使指定了-Werror,也保留警告标志<flag>作为警告。 |
-W<flag> | 启用警告标志<flag>。 |
-Wno-<flag> | 禁止警告标志<flag>。 |
-w | 禁止所有警告。注意,这个选项是小写的w。 |
-Weverything | 打开所有警告。 |
-Wpedantic | 如果代码违反严格的ISO C和ISO c++,则生成警告。 |
-pedantic | 如果代码违反严格的ISO C和ISO c++,则生成警告。 |
-pedantic-errors | 如果代码违反严格的ISO C和ISO c++,则生成错误。 |
-f[no-]color-diagnostics | 该选项控制Clang是否以彩色打印诊断信息,当检测到支持彩色的终端时,默认为打开。 |
-f[no-]diagnostics-show-hotness | 在诊断行中启用配置文件热度信息(hotness)。 |
-f[no-]diagnostics-fixit-info | 启用诊断输出中的FixIt信息。这个选项(默认为on)控制Clang是否在它知道如何修复特定诊断的情况下打印信息。 |
3 使用示例
比如有一个file.c文件如下:
#include <stdlib.h>
#include <stdio.h>
void function (int x) {
int i;
int y=i+x;
/* 第三个 %d 缺少对应参数*/
printf("Result of %d plus %d is %d\n", i, x);
/* call这个函数在当前文件中没有被声明过,所以是隐式声明 (implicit declaration)*/
call();
return;
}
当使用如下命令进行编译时:
armclang --target=aarch64-arm-none-eabi -march=armv8 -c file.c
默认情况下,编译器会检查 printf() 函数声明的格式,确保 % 与传入的参数个数是否匹配,因此armclang会报如下警告信息:
file.c:9:36: warning: more '%' conversions than data arguments [-Wformat]
printf("Result of %d plus %d is %d\n", i, x);
^
此外,在默认情况下,对 .c 文件,armclang使用 gnu11 的标准进行编译,该语言标准不支持隐式函数声明,因此会报如下警告:
file.c:11:3: warning: implicit declaration of function 'call' is invalid C99 [-Wimplicit-function-declaration]
call();
^
关闭所有warning, 使用 -w
:
armclang --target=aarch64-arm-none-eabi -march=armv8-a -c file.c -w
关闭 -Wformat
带来的warning, use -Wno-format
:
armclang --target=aarch64-arm-none-eabi -march=armv8-a -c file.c -Wno-format
将 -Wformat
消息产生的warning作为 error报告, use -Werror=format
:
armclang --target=aarch64-arm-none-eabi -march=armv8-a -c file.c -Werror=format
默认情况下,某些诊断消息被抑制。查看所有诊断消息, use -Weverything
:
armclang --target=aarch64-arm-none-eabi -march=armv8-a -c file.c -Weverything
4 使用 pragma控制诊断信息
除了在armclang命令行中添加诊断消息选项,armclang还支持在源代码中添加选项,详情可以参考文档:Clang Compiler User’s Manual — Clang 17.0.0git documentationhttps://clang.llvm.org/docs/UsersManual.html#controlling-errors-and-warnings
Clang还可以通过在源代码中使用pragma来控制启用哪些诊断。这对于关闭源代码部分中的特定警告非常有用。为了与现有源代码兼容,Clang支持GCC的pragma,以及一些扩展。pragma可以控制任何可以从命令行使用的警告。警告可以设置为忽略、警告、错误或致命。下面的示例代码将告诉Clang或GCC忽略-Wall警告:
#pragma GCC diagnostic ignored "-Wall"
#pragma clang diagnostic ignored "-W<name>"
// 忽略由<name>指定的诊断消息。
#pragma clang diagnostic warning "-W<name>"
// 将<name>指定的诊断消息设置为警告级别。
#pragma clang diagnostic error "-W<name>"
// 将<name>指定的诊断消息设置为error 级别。
#pragma clang diagnostic fatal "-W<name>"
// 将<name>指定的诊断消息设置为致命错误 fatal error 级别。
#pragma clang diagnostic push
// 保存诊断状态,以便恢复。
#pragma clang diagnostic pop
// 恢复上次保存的诊断状态。
用户也可以使用命令行选项 -W<name>来禁止或更改消息的级别,但是该更改适用于整个编译,而不是当前源文件。
关于 push 和 pop的操作,可以看如下示例:
#if foo
#endif foo /* no warning when compiling with -Wextra-tokens */
#pragma clang diagnostic push
#pragma clang diagnostic warning "-Wextra-tokens"
#if foo
#endif foo /* warning: extra tokens at end of #endif directive */
#pragma clang diagnostic pop
当使用如下命令编译时:
armclang --target=arm-arm-none-eabi -march=armv7-a -c foo.c -o foo.o -Wno-extra-tokens
编译器只会对第二个 #endif foo 示例发出警告:
foo.c:8:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
#endif foo /* warning: extra tokens at end of #endif directive */
^
//
1 warning generated.
5 armasm 和 armlink的消息格式
armasm 和 armlink的消息格式如下:
type: prefix id suffix: message_text
- <type>, 有以下类型选项:
- Internal fault : 内部故障,内部故障表示工具内部出现问题。请与您的供应商联系并提供反馈。
- Error:错误表示导致工具停止的问题。
- Warning:警告表示异常情况可能表明存在问题,但该工具仍在继续。
- Remark:备注,备注是常用的工具用法,但有时不符合常规。默认情况下不显示这些诊断信息。工具继续运行。
- <prefix>, 有以下类型选项:
A
-armasm
L
-armlink
orarmar
Q
-fromelf
- <id>,唯一的数字消息标识符。
- <suffix>,消息的类型:
E
- ErrorW
- WarningR
- Remark
- <message_text>,消息内容。
比如下面的armlink的错误消息:
Error: L6449E: While processing /home/scratch/a.out: I/O error writing file '/home/scratch/a.out': Permission denied
详情可以参考文档:
Arm Compiler for Embedded Errors and Warningshttps://developer.arm.com/documentation/100074/0620/Linker-Errors-and-Warnings/List-of-the-armlink-error-and-warning-messages
6 armasm
, armlink
, armar
, fromelf等工具控制诊断消息选项
--brief_diagnostics
armasm
only。使用较短形式的诊断输出。原始的源行不显示,并且当错误消息文本太长而不能放在单行中时,错误消息文本不会被换行。
--diag_error=<tag>[,<tag>]...
将指定的诊断消息设置为“错误”。使用 --diag_error=warning
可以将所有的warning当作error.
--diag_remark=<tag>[,<tag>]...
将指定的诊断消息设置为Remark级别。
--diag_style=arm|ide|gnu
指定诊断消息的显示样式
--diag_suppress=<tag>[,<tag>]...
禁止指定的诊断信息. 使用 --diag_suppress=error
将禁止所有可以被降级的error, 或者使用 --diag_suppress=warning
可以关闭所有的warning。降低诊断消息的级别可能会阻止工具报告重要错误。Arm建议,除非用户了解对软件的影响,否则不要降低诊断的级别。
--diag_warning=<tag>[,<tag>]...
将指定的诊断消息设置为警告级别。使用--diag warning=error 将设置所有可以降级错误为警告。
--errors=<filename>
将诊断消息的输出重定向到指定文件。
--remarks
armlink
only. 启用 remark 消息的显示。
7 参考文章
Arm Compiler for Embedded Errors and Warningshttps://developer.arm.com/documentation/100074/0620/Linker-Errors-and-Warnings/List-of-the-armlink-error-and-warning-messages
Controlling diagnostic messageshttps://developer.arm.com/documentation/100748/0620/Using-Common-Compiler-Options/Controlling-diagnostic-messages?lang=en Clang Compiler User’s Manual — Clang 17.0.0git documentationhttps://clang.llvm.org/docs/UsersManual.html#controlling-errors-and-warnings