gpt4 book ai didi

c++ - 有没有办法禁止 C++ 中的指针比较?

转载 作者:太空狗 更新时间:2023-10-29 20:39:45 25 4
gpt4 key购买 nike

我有一个(有效的)代码库,我想在其中向类层次结构添加类似 is_equivalent 成员的内容。散布在整个代码库中的比较如下:

if (foo == bar) ...

其中 foobar 是指向类层次结构中对象的普通指针。我想介绍如下用法(作为基类中的虚函数):

if (foo->is_equivalent(bar)) ...

这样就放宽了“平等”的概念。一个具体的几何示例可能是一个形状层次结构,其中一个 Circle 应该被认为等同于一个具有相同长轴和短轴的 Ellipse(不是一个完美的类比)。

我想做的是让编译器帮助我找到我进行直接指针比较的所有实例。我的一个想法是提供类似 operator==(const Shape *, const Shape *) 的东西,但 C++ 甚至不允许这样做。

有些指针比较可能需要保留指针比较,有些则需要改为虚方法调用。我需要看看每一个。有哪些方法可以识别所有这些类型的比较?暂时中断构建或执行都可以。有很好的测试覆盖率。

我已阅读问题 C++ Trick to avoid pointer comparison这是相似的,但更受限制,因为接受的答案假定存在工厂类。

最佳答案

您可以编写自定义代码分析工具。这是我使用 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;
}

我使用的示例文件是这个虚构的 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

关于c++ - 有没有办法禁止 C++ 中的指针比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26722696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com