有什么方法可以为函数指针比较生成警告吗?
Any way to generate warnings for function-pointer comparisons?
我花了很长时间才发现我的代码中有一个错误是由 /OPT:ICF
:
触发的
Because /OPT:ICF can cause the same address to be assigned to different functions or read-only data members (const variables compiled by using /Gy), it can break a program that depends on unique addresses for functions or read-only data members.
(我一直在存储和比较函数指针的相等性,当链接器丢弃相同的函数时中断。)
现在我需要找到我可能做过这种事的每个地方。
测试用例当然是微不足道的:
//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }
我已尝试 -Wall
、-Wextra
、-Weverything
、-pedantic
等,但其中 none 会生成警告。
是否有任何编译器选项或工具(无论是 Visual C++、GCC、Clang 还是其他的一部分)可以分析我的代码并告诉我在哪里比较函数相互指针,就像上面的代码一样?
Is there any compiler option or tool (whether part of Visual C++, GCC, Clang, or other) that can analyze my code and tell me where I'm comparing function pointers with each other, like in the code above?
我不确定是否存在这样的编译器选项。
不过,有这样的工具。整洁。您可以编写自己的 clang-tidy 检查,如果您遵循 this blog,这实际上非常容易。具体来说,AST 已经附带了一堆匹配器,它们应该可以处理您想要的用例。
类似这样的方法似乎有效:
binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(ignoringImpCasts(declRefExpr(hasType(functionType())))),
hasRHS(ignoringImpCasts(declRefExpr(hasType(functionType())))))
在 OP 中标记示例:
fp.cxx:3:25: note: "root" binds here
int main(void) { return test1 == test2; }
^~~~~~~~~~~~~~
这特别适用于 OP 案例,但实际上您必须更明确地匹配所有其他可能的案例:
const auto AnyFunc = ignoringImpCasts(declRefExpr(hasType(anyOf(
functionType(),
pointsTo(functionType()),
references(functionType())))));
Finder->AddMatcher(binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(AnyFunc),
hasRHS(AnyFunc)).bind("op"), this);
或接近那种效果的东西。
我花了很长时间才发现我的代码中有一个错误是由 /OPT:ICF
:
Because /OPT:ICF can cause the same address to be assigned to different functions or read-only data members (const variables compiled by using /Gy), it can break a program that depends on unique addresses for functions or read-only data members.
(我一直在存储和比较函数指针的相等性,当链接器丢弃相同的函数时中断。)
现在我需要找到我可能做过这种事的每个地方。
测试用例当然是微不足道的:
//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }
我已尝试 -Wall
、-Wextra
、-Weverything
、-pedantic
等,但其中 none 会生成警告。
是否有任何编译器选项或工具(无论是 Visual C++、GCC、Clang 还是其他的一部分)可以分析我的代码并告诉我在哪里比较函数相互指针,就像上面的代码一样?
Is there any compiler option or tool (whether part of Visual C++, GCC, Clang, or other) that can analyze my code and tell me where I'm comparing function pointers with each other, like in the code above?
我不确定是否存在这样的编译器选项。
不过,有这样的工具。整洁。您可以编写自己的 clang-tidy 检查,如果您遵循 this blog,这实际上非常容易。具体来说,AST 已经附带了一堆匹配器,它们应该可以处理您想要的用例。
类似这样的方法似乎有效:
binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(ignoringImpCasts(declRefExpr(hasType(functionType())))),
hasRHS(ignoringImpCasts(declRefExpr(hasType(functionType())))))
在 OP 中标记示例:
fp.cxx:3:25: note: "root" binds here
int main(void) { return test1 == test2; }
^~~~~~~~~~~~~~
这特别适用于 OP 案例,但实际上您必须更明确地匹配所有其他可能的案例:
const auto AnyFunc = ignoringImpCasts(declRefExpr(hasType(anyOf(
functionType(),
pointsTo(functionType()),
references(functionType())))));
Finder->AddMatcher(binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(AnyFunc),
hasRHS(AnyFunc)).bind("op"), this);
或接近那种效果的东西。