How to get g++ to warn on unused member variables - c++

g++ generates warnings for unused local variables. Is it possible to have g++ warn for unused class member variables and/or global variables?
class Obj {
public:
Obj(int a, int b) : num1(a), num2(b) {}
int addA(int i) {
return i + num1;
}
private:
int num1;
int num2;
};
How do I get g++ to warn me that num2 is unused?
UPDATE:
I am currently compiling with:
g++ -Wall -Wextra -pedantic *.cc -o myprogram

Clang's -Wunused-private-field enables the warning you're asking for. On your code base, it shows:
$ clang -Wunused-private-field /tmp/nic.cpp
/tmp/nic.cpp:10:22: warning: private field 'num2' is not used [-Wunused-private-field]
int num2;
^
1 warning generated.

I'm not aware of any such warning. Additionally I'll speculate that the reason it doesn't exist is because it can't be reliably generated in all cases, so they elected to not spend effort making it work for some subset of cases. For example, if the class friends another function that's in a library, the compiler would have no way of knowing if that library mutated any particular class attribute or not.

You can use cppcheck (download). cppcheck --enable=style does exactly what you need, among other useful things.

Related

Calling a function with uninitalized struct variable as a parameter doesn't produce a warning

I have the following code in c++:
#include <iostream>
typedef struct Pair{
int x;
int y;
}Pair;
void dumFun(Pair p){}
int main() {
Pair p;
if (0){
p = {1,2};
}
dumFun(p);
return 0;
}
When I compiled the code, I expected to get a warning for the line with dumFun(p) since I'm calling a function with an uninitialized variable.
What I actually want is that my Makefile will give me warning for uninitialized scalar variable issues that I see with the tool Coverity.
Tried to use flag -Wall and I thought it shows warnings for unused variables usage as this - but it doesn't.
Is there any flag to use on a Makefile that will show me warning for the line I wrote above?
You did not tell the compiler, but at least in Clang there is no warning that would catch this. -Weverything shows all possible warnings, and you can use it to find the specific parameter needed to trigger each warning. Demonstration with -Weverything shows no warnings.
I did not find a suitable parameter in GCC either.

How can I make GCC/Clang warn about the use of uninitialized members?

I am compiling the code behind
class Test {
public:
Test() {}
int k;
};
int main() {
Test t;
std::cout << t.k << "\n";
}
like
g/clang++ main.cpp -Wall -Wextra --std=c++14 -o exe; ./exe
Why neither of the compilers does not warn me about indeterminate value of the integer is not it a very serious potential bug? How to enable a warning for indeterminate initializations?
For this example, GCC gives me the desired warning when I give it -O1 (or higher).
Presumably whatever mechanism it uses to detect this is tied into the optimisation effort level somehow. It's a notoriously hard thing to do.
Ensure that you heed your release-build warnings as well as debug-build warnings.

Why can a const Class& be initialized to itself?

I was hit by a very stupid but hard to detect bug today. Here is the relevant code:
class Vector;
class PointIterator {
const Vector & x;
const Vector & yv;
PointIterator(const Vector & xv, const Vector & yvo) :
x(xv), yv(yv) { ;};
// ^^ here is wrong
};
Why is such a code legal C++ ? Is there any situation where you could make use of the yv variable ? I'm aware of similar questions about int x = x+1;, (see this question) but while the latter isn't properly initialized, you still can use the x variable, while in the code above, I don't think you can make any use of yv.
Bonus point: is there any compilation option that would have made me detect this ? (preferably using gcc, but I also use clang), besides the "unused argument" warning (I have quite a few of those, I know I should clean them up).
If you compile with g++ -O0 -g main.cpp -Wall -pedantic -Wextra -std=c++14 -o go
main.cpp: In constructor 'PointIterator::PointIterator(const Vector&, const Vector&)':
main.cpp:11:5: warning: 'PointIterator::yv' is initialized with itself [-Winit-self]
PointIterator(const Vector & xv, const Vector & yvo) :
^~~~~~~~~~~~~
main.cpp:11:53: warning: unused parameter 'yvo' [-Wunused-parameter]
PointIterator(const Vector & xv, const Vector & yvo) :
As you can see, you get the warning two times. One for the self init and one for the unused parameter. Fine!
The same for clang:clang++ -O0 -g main.cpp -Wall -pedantic -Wextra -std=c++14 -o go
main.cpp:12:19: warning: reference 'yv' is not yet bound to a value when used
here [-Wuninitialized]
x(xv), yv(yv) { ;};
^
main.cpp:11:53: warning: unused parameter 'yvo' [-Wunused-parameter]
PointIterator(const Vector & xv, const Vector & yvo) :
^
main.cpp:8:20: warning: private field 'x' is not used [-Wunused-private-field]
const Vector & x;
So clang reports also the problem, that the uninitialized ref is used before init. Fine!
What you learn:
* use multiple compilers in highest warning level to get all warnings!
That is what we do for all our code, especially in unit tests connected to code coverage.
And you should use a coding guideline which makes it easy to detect such problems by review. Maybe use "m_" for class vars or "_var" for parameters or whatever you prefer. Var names with only a list of letters instead of speaking names is a not so well.

disable enum assignment g++ in if statement

I would like to treat assignment in an if statement as error:
#include <cstdio>
enum some {
a,
b
};
void foo(some e) {
if (e = a) {
puts("yes");
} else {
puts("no");
}
}
int main() {
foo(a);
return 0;
}
This seems like a sane thing to do, except that I'd like to have something like this too:
boost::optional<int> optionalValue;
if (const auto& value = optionalValue) {
}
-Wall gives me enum.cpp:9: warning: suggest parentheses around assignment used as truth value, but I would like to have something more specific than -Wall
You could declare e to be const. Then assignment would be an error.
Or, you can tell g++ to treat warnings as errors with -Werror. Then, coupled with the appropriate warning setting, any assignment in a if expression will be an error. You can enable only this class of warnings with -Wparentheses However, do note that sometimes it's not a mistake, but done on purpose. Which is why g++ suggests using parentheses to disambiguate from accidental assignment.
If you use a more recent version of g++ then it tells you which warning flag corresponds to which diagnostic. Using g++ 4.9.2 your code gives :
m.cc:9:14: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
This tells you that the error comes from the flag -Wparentheses, which is a subset of -Wall.
You can instruct g++ to treat all warnings as errors by using -Werror. But if you only want to treat this particular warning as an error then you can use:
-Werror=parentheses
This version of g++ does not warn for your suggested code const auto& value = optionalValue, so perhaps it's time to upgrade your compiler version.

gcc/g++ internal error (c++ templated lambda)

i was just making a few changes to my program, when all of a sudden g++ complained with an internal compiler error.
Clang however compiles it without any problems and also does not give any warnings, that would indicate anything weird.
I distilled the problem down to this:
#include <functional>
template<typename T>
class A{
T someVar;
};
template<typename T>
class B {
int x;
std::function<A<double>(A<int>&)> someLambda = [&](A<int>& aInt){
int xVar = x;
A<double> aRet;
return aRet;
};
};
int main(int argc, char** argv){
B<int> a;
return 0;
}
I tried both GCC 4.9.2 and 4.8.4, with both failing (internal compiler error).
Flags I used:
g++ -std=c++11 -O0 -g -Wall main.cpp -o gccBin
clang++ -std=c++11 -O0 -g -Wall main.cpp -o clangBin
main.cpp: In instantiation of 'struct B<int>::<lambda(class A<int>&)>':
main.cpp:10:7: required from here
main.cpp:14:24: internal compiler error: in tsubst_copy, at cp/pt.c:12569
int xVar = x;
^
libbacktrace could not find executable to open
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Clang++(3.5.1) compiles it without a problem, as I mentioned.
I also tried multiple machines, everywhere the same.
Is there some kind of error I overlooked? I searched a bit on the internet and the only similar problems i could find should have been fixed by now (as the bugtracker states).
Could maybe someone try and run this code on their machine or give other advice?
Thank you,
Lazarus
It's a compiler bug. Just go ahead and file a bug report to the GCC dudes!