我想知道是否有针对这种情况的编译器选项或 clang-tidy 检查:
#include<iostream>
#include <ostream>
int glob = 12;
int& test(int d){
std::cout << &glob << std::endl;
return glob;
}
int main() {
auto a = test(10);
std::cout << &a << std::endl;
return 0;
}
如果我突然忘记将
&
放在auto
之后,我会在输出中看到不同的地址,这是预期的,但是是否有任何编译器标志或clang-tidy标志警告我是吗?
clang-query
检查使用类型 auto
声明变量的模式
(与 auto&
不同)并通过调用来初始化它
返回引用的函数。
以下 shell 脚本使用这样的方式调用
clang-query
匹配表达式:
#!/bin/sh
PATH=$HOME/opt/clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH
# In the following, the comments are seen and ignored by clang-query
# (not the shell). But beware that clang-query has odd rules for where
# comments can go, and poor error reporting if the rules are violated.
query='m
varDecl( # Report any variable declaration
hasType( # whose declared type
autoType() # is `auto`,
),
hasInitializer( # and that has an initializer
implicitCastExpr( # that is an implicit conversion
hasSourceExpression( # from
callExpr( # a function call expression
callee( # where the callee
functionDecl( # is a directly named function
returns( # whose return type
referenceType() # is a reference.
)
)
)
)
)
)
)
).bind("decl")
'
if [ "x$1" = "x" ]; then
echo "usage: $0 filename.cc -- <compile options like -I, etc.>"
exit 2
fi
# Run the query. Setting 'bind-root' to false means clang-query will
# not also print a redundant "root" binding.
clang-query \
-c="set bind-root false" \
-c="$query" \
"$@"
# EOF
输入以下内容:
// test.cc
// Cases for `auto` declaring non-ref initialized from ref.
int &getref();
int getnonref();
void g(int &refparam)
{
// ref -> ref
auto &r2r = getref(); // not reported: no conversion
// ref -> nonref
auto r2nr = getref(); // reported
// nonref -> nonref
auto nr2nr = getnonref(); // not reported: no conversion
// nonref -> ref: Syntax error.
//auto &nr2r = getnonref();
auto rp2nr = refparam; // not reported: not a call
}
// EOF
它产生输出:
$ ./cmd.sh test.cc --
Match #1:
$PWD/test.cc:14:3: note: "decl" binds here
auto r2nr = getref(); // reported
^~~~~~~~~~~~~~~~~~~~
1 match.
在匹配表达式中,我将报告限制为初始化程序 函数调用。 但是,根据您的需求,您可能想要 删除整个
hasSourceExpression
匹配器(所以
implicitCastExpr
后面跟着 ()
),从而报告任何 auto
使用隐式转换初始化的声明,因为可以说任何
这种情况是“令人惊讶的”,也许是无意的。
我还没有对这个匹配器进行任何大规模的测试或调整,所以它 可能需要进一步调整才能用于生产。
将
clang-query
集成到构建或测试中的过程
工作流程与 clang-tidy
的工作流程基本相同,假设
后者是通过直接调用完成的。