未定义符号是实现消毒剂检查的函数。如果您查看生成的代码:
无消毒剂:
_Z3foof: # @_Z3foof
.cfi_startproc
# BB#0:
xorps %xmm1, %xmm1
divss %xmm1, %xmm0
ret
使用消毒剂:
_Z3foof: # @_Z3foof
.cfi_startproc
.long 1413876459 # 0x54460aeb
.quad _ZTIFffE
# BB#0:
pushq %rax
.Ltmp1:
.cfi_def_cfa_offset 16
movss %xmm0, 4(%rsp) # 4-byte Spill
movd %xmm0, %esi
movl $__unnamed_1, %edi
xorl %edx, %edx
callq __ubsan_handle_divrem_overflow
xorps %xmm1, %xmm1
movss 4(%rsp), %xmm0 # 4-byte Reload
divss %xmm1, %xmm0
popq %rax
ret
您会看到它添加了使用该函数进行检查的代码。
编译器应该自动链接到适当的消毒剂库,然后对我来说下面的完整程序:
float foo(float f) { return (f / 0); }
int main() {
foo(1.0f);
}
执行时产生以下输出:
main.cpp:1:32: runtime error: division by zero
我使用命令构建并运行clang++ -fsanitize=undefined main.cpp && ./a.out
如果您想要编译时检查,您想要启用更多编译器警告或静态分析器。但是,对于浮点除以零错误,似乎没有任何警告或静态分析检查。
这是一个生成分析器报告的程序:
#include <malloc.h>
int main() {
int *i = (int*) malloc(sizeof(int));
}
用它编译clang++ -std=c++11 main.cpp
不会产生诊断,但用clang++ -std=c++11 --analyze main.cpp
它编译会报告以下内容:
main.cpp:4:10: warning: Value stored to 'i' during its initialization is never read
int *i = (int*) malloc(sizeof(int));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:5:1: warning: Potential leak of memory pointed to by 'i'
}
^
也可以使用 -Weverything [-Wunused-value] 检测到死存储,但泄漏仅由分析器检测到。
默认情况下,完整的分析结果将写入 plist 文件。您还可以使用以下命令运行分析器:
clang++ --analyze -Xanalyzer -analyzer-output=text main.cpp
clang++ --analyze -Xanalyzer -analyzer-output=html -o html-dir main.cpp
在标准输出或通过带注释的源代码的 html 显示,而不是在 plist 中获取检测到的问题的详细演练。
此处列出了分析器检查。
请注意,为了最好地工作,分析器需要分析整个程序,这意味着它需要与构建系统相关联。通常的界面是通过 IDE (Xcode) 或scan-build
带有 make 的工具。CMake 具有一些 clang 功能,例如生成 clang JSON 编译数据库文件,但我不确定 CMake 是否有任何内置支持 clang 分析器。