In the process of automatically renaming many variables in a big project I may have created a lot of things like these:
class Foo {
int Par;
void Bar(int Par) {
Par = Par; // Nonsense
}
};
Now I need to identify those locations to correct them. E.g. into "this->Par = Par;". Unfortunately the Visual C++ Compiler des not give me any comment about it even with all warnings on. I remember there once was a warning about it. It said "Code has no effect" or something. But it seems to be gone maybe because some people used that practice to avoid "unreferenced parameter" warnings. Is there a way to re-activate that warning? Does GCC warn here? Any Idea?
A couple of compilers can generate warnings on this:
-Wshadow
option. (Specifically, while they don't warn about the meaningless assignment, they do warn about the local variable Par
shadowing the member variable Par
- you may or may not like this.)Par = Par
is useless, but it can warn that Par
isn't used after it's assigned to, which should meet your needs.I suspect a tool like PC-Lint could also identify code like this.
Another solution is to mark your parameters as const
:
class Foo {
int Par;
void Bar(const int Par) {
Par = Par; // Compiler error!
}
};
const
on pass-by-value parameters is not part of the function signature, so you only need to add it to the function definitions within your .cpp
file, not your function declarations within your .h
file. In other words, it's legal to do this:
// foo.h
class Foo {
int Par;
void Bar(int Par);
};
// foo.cpp
void Foo::Bar(const int Par) { ... }
As kaptnole pointed out, the regex I crafted could be used directly in visual studio. Your pattern is:
^[\s\t]*([a-zA-Z_0-9])[\s\t]=[\s\t]\1[\s\t];[\s\t]*$
Follow the directions listed here:
http://msdn.microsoft.com/en-us/library/2k3te2cs%28VS.80%29.aspx
...and happy finding (without ever touching Perl!).
This perl one liner will do it for you:
perl -n -e'/^[\s\t]*([a-zA-Z_0-9]*)[\s\t]*=[\s\t]*\1[\s\t]*;[\s\t]*$/&&print "$. $_"' test_me && echo
I tested it on a file containing the following and it correctly detected all matches:
hi = hi;
hi= hi ;
hi=hi ;
Output....
xxxxx@yyyy% perl -n -e'/[\s\t]*([a-zA-Z_0-9]*)[\s\t]*=[\s\t]*\1[\s\t]*;[\s\t]*$/&&print "$. $_"' test_me && echo
1 hi = hi;
2 hi= hi ;
3 hi=hi ;
xxxxx@yyyy%
My first thought was to do it in Awk, but apparently Awk doesn't store its matches! :(
But hey, this Perl script is pretty snazzy itself... it even prints the line numbers of the find!
EDIT 1
And to answer your other question, I compiled a simple test program with such an assignment inside main with the "-pedantic" and "-Wall" flags using gcc and g++ and received no warnings in either... so I guess it doesn't warn you of this kind of redundancy.
Here's my test program:
int main (int argc, char *argv[]) {
int bob=5;
bob=bob;
return 0;
}
EDIT 2
Please note my above perl script does NOT check to see if there's a local variable of an identical name inside a function. In that case the statement might be valid, but poor style (still might be good to warn about).
And as Josh points out, the flag "-Wshadow" WILL warn about this in gcc/g++ in this specialized case.
I would suggest following Josh's advice about using const for static function arguments. In fact, any variable not passed by reference should generally be const
e.g.
void hello_world_print_numbers(int number_1, int number_2, int number_3) {
...
}
is a misassignment waiting to happen, so instead use:
void hello_world_print_numbers(const int number_1, const int number_2, const int number_3) {
...
}
...likewise in general with pointers, except in the case of passed pointers to arrays (and be careful there to pass in proper array bounds!).
void hello_world_print_numbers(const int * number_1, const int * number_2, const int * number_3) {
...
}
EDIT 3
I forgot my ^
at the start of my regex. While seemingly trivial this causes it to improperly tag assignments of type my_class->name=name;
. This was wisely pointed out by RC. The regex is now fixed and should no longer have this issue. Thanks RC!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With