Gre*_*ill 3 c++ pointers equality
我有一个(工作)代码库,我想在is_equivalent类层次结构中添加类似成员的东西.在整个代码库中分散了比较
if (foo == bar) ...
Run Code Online (Sandbox Code Playgroud)
where foo和bar是类层次结构中对象的普通指针.我想介绍如下的用法(作为基类中的虚函数):
if (foo->is_equivalent(bar)) ...
Run Code Online (Sandbox Code Playgroud)
这样就可以放松"平等"的概念.具体的几何示例可能是形状层次结构,其中a Circle应该被认为等同于Ellipse具有相等的长轴和短轴(不是完美的类比).
我想要做的是让编译器帮助我找到我已经完成直接指针比较的所有实例.我有一个想法是提供类似的东西,operator==(const Shape *, const Shape *)但C++甚至不允许这样做.
某些指针比较可能需要保持指针比较,但有些需要更改为虚拟方法调用.我需要看看每一个.有哪些方法可以识别所有这些类型的比较?暂时中断构建或执行是好的.有很好的测试覆盖率.
您可以编写自定义代码分析工具.这是我使用的最小(而且相当简单)的例子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;
// retrieve physical location of AST node
clang_getSpellingLocation(begin, &file, NULL, NULL, &begin_offset);
clang_getSpellingLocation(end, NULL, NULL, NULL, &end_offset);
length = end_offset - begin_offset;
// Open the file, error checking omitted for clarity
CXString xfname = clang_getFileName(file);
const char *fname = clang_getCString(xfname);
FILE *fhndl = fopen(fname, "r");
clang_disposeString(xfname);
// Read the source
char buf[length + 1];
fseek(fhndl, begin_offset, SEEK_SET);
fread(buf, length, 1, fhndl);
buf[length] = 0;
fclose(fhndl);
// and print it
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;
}
Run Code Online (Sandbox Code Playgroud)
我使用的示例文件是这个虚构的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;
}
Run Code Online (Sandbox Code Playgroud)
我的工具打印了这个:
Comparison: f == f
Comparison: b == b
Comparison: f == b
Run Code Online (Sandbox Code Playgroud)