有没有一种方法可以禁止C++中的指针比较
Is there a way to disallow pointer comparison in C++?
我有一个(工作的)代码库,我想在其中向类层次结构添加类似is_equivalent
成员的内容。散布在整个代码库中的是类似的比较
if (foo == bar) ...
其中CCD_ 2和CCD_。我想介绍如下用法(作为基类中的虚拟函数):
if (foo->is_equivalent(bar)) ...
从而放松了"平等"的概念。具体的几何示例可能是形状层次,其中Circle
应被视为等效于具有相等长轴和短轴的Ellipse
(不是完美的类比)。
我想做的是让编译器帮我找到所有我做过直接指针比较的实例。我的一个想法是提供类似operator==(const Shape *, const Shape *)
的东西,但C++甚至不允许这样做。
有些指针比较可能需要保持指针比较,但有些需要更改为虚拟方法调用。我需要看看每一个。有什么方法可以识别所有这些类型的比较?暂时中断生成或执行都可以。有相当好的测试覆盖率。
我读过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: %sn", 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
相关文章:
- ISO C++禁止声明没有类型的"setInputNombre"
- 禁止显示由于常量为零而比较始终为假的警告
- 禁止在控制台上记录谷神星
- 禁止显示有关包含文件中 #pragma 包的警告
- 禁止指针和整数之间的比较C++
- ISO C++禁止指针和整数 [-fpermissive] [c++] 之间的比较
- 为什么我会收到此警告:ISO c++ 禁止可变长度数组"v"[-Wvla]
- 当空基类也是成员变量时,为什么禁止空基优化?
- ISO 中禁止可变长度数组 C++崇高文本中的错误 3.
- 标记类以禁止操作
- 禁止子函数调用父级的抽象(或虚拟)函数
- Linux C 只禁止我的程序使用核心转储
- 错误:ISO C++禁止可变长度数组"subVec"[-Werror=vla]
- 如何禁止在 g++ 中使用但从未定义警告的内联函数
- 捕获/禁止发送到 std::cout 的 OpenCV 警告
- Qt 错误 iso c++ 禁止指针和整数之间的比较 -permissive
- 为什么禁止建造 istreams?
- 是否可以禁止在for循环体内部修改循环变量
- 在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗
- 禁止复制构造函数和赋值运算符singleton类