您可以编写一个定制的代码分析工具。以下是我使用
libclang
构建的最小(而且相当琐碎)示例。它会过滤源代码中的每个二元运算符。通过不断完善,您可以从 AST 中收集所有指针相等比较操作。
#include <clang-c/Index.h>
#include <stdio.h>
static void printBinOp(CXCursor cursor)
{
CXSourceRange range = clang_getCursorExtent(cursor);
CXSourceLocation begin = clang_getRangeStart(range);
CXSourceLocation end = clang_getRangeEnd(range);
CXFile file;
unsigned begin_offset, end_offset, length;
clang_getSpellingLocation(begin, &file, NULL, NULL, &begin_offset);
clang_getSpellingLocation(end, NULL, NULL, NULL, &end_offset);
length = end_offset - begin_offset;
CXString xfname = clang_getFileName(file);
const char *fname = clang_getCString(xfname);
FILE *fhndl = fopen(fname, "r");
clang_disposeString(xfname);
char buf[length + 1];
fseek(fhndl, begin_offset, SEEK_SET);
fread(buf, length, 1, fhndl);
buf[length] = 0;
fclose(fhndl);
printf("Comparison: %s\n", buf);
}
static enum CXChildVisitResult ptrCompVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
if (clang_getCursorKind(cursor) == CXCursor_BinaryOperator) {
printBinOp(cursor);
}
return CXChildVisit_Recurse;
}
int main()
{
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit tu = clang_parseTranslationUnit(index, "foo.cpp", NULL, 0, NULL, 0, CXTranslationUnit_None);
clang_visitChildren(clang_getTranslationUnitCursor(tu), ptrCompVisitor, NULL);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);
return 0;
}
我使用的示例文件是这个想象中的C++源代码文件(命名为
foo.cpp
):
class Foo {
int foo;
};
class Bar {
int bar;
}
int main()
{
void *f = new Foo();
void *b = new Bar();
bool alwaystrue_1 = f == f;
bool alwaystrue_2 = b == b;
return f == b;
}
我的工具打印出了这个:
Comparison: f == f
Comparison: b == b
Comparison: f == b
if (foo == bar)
是在比较对象foo
是否为bar
相同的对象,这与char *foo = "abc"; char bar[] = "abc"; if (foo == bar)
相同 - 这是不正确的,因为foo
和bar
指向内存中的不同位。如果你想要比较*foo == *bar
,那么你可以通过实现operator==
在C ++中完成你希望做的事情。 - Mats Petersson