C++ : how to make sure all variables are initialized? - c++

Recently I had lots of trouble with a non initialized variable.
In Java, the default value of variable is null, therefore an exception is likely to be thrown when if the non-initialized variable is used. If I understood, in C++, the variable is initialized with whatever data turns out to be in the memory. Which means that the program is likely to run, and it might be hard to even know there is something wrong with it.
What would be the clean way to deal with this ? Is there some good programming habit that would reduce the risk ? In my case, the variable was declared in the header file and should have been initialized in the cpp file, which is an example of things that makes error more likely.
thx
Edition after receiving few answers:
My apologies, my question was not specific enough.
The answer I get to use flag for the compilers to get informed of non-initialized variables will be useful.
But there are rare cased variables can not be initialized at the beginning, because depending on the behavior of your system.
in header file
double learnedValue;
in cpp file
/* code that has nothing to do with learnedValue
...
*/
learnedValue = a*b*c; // values of a, b and c computed in the code above
/*code making use of learned value
...
*/
Now what happened is that forgot the line "learnedValue=a*b*c".
But the program was working good, just with value of learnedValue initialized with whatever what was in the memory when it was declared.
In Java, such error is not an issue, because the code making use of learned value is likely to crash or throw an exception (at least you get to know what was wrong).
In C++, you can apparently be happy and never get to know there is a problem at all. Or ?

Pls make sure you have appropriate warning levels set while compiling your program.
Compilers issue appropriate warning whenever un-initialized variables are used.
On g++, -Wall compiler option would show all warnings.
On Visual studio, you might have to use warning level 4.
Also, there are some static code analysis tool available in the market.
cppCheck is one such tool available for free.

You should not define a variable in a header (only declare it). Otherwise you will get other errors when you include the header in several .cpp files.
When actually defining a variable, you can also give it an initial value (like 0). In C++ it is also common to defer the definition of (local) variables until you have a value to assign to them.
In the header file
extern double learnedValue;
^^^^^^
In the cpp file
double learnedValue = 0;
/* code that has nothing to do with learnedValue
...
*/
learnedValue = a*b*c; // values of a, b and c computed in the code above
/*code making use of learned value
...
*/

you can define the variables on the spot they are declared

c++11 allows you to initialize variables inside class. If that is not implemented by the compiler yet then the constructor initialization list is the area to check.

The C# can initialize the variable. But C++ not, so when use a pointer without initialized, it always throw exception. You should make a good habit to initialize all the variables in the class constructor.

Related

C++ Give compiler error for setting a (static) const global variable to another static const variable

Is it possible for clang to give a compiler error if you accidentally set a const global variable to another static const variable in C++ (in different translation units).
Since the behaviour is pretty much undefined, it would be very useful to detect if doing this accidentally.
EDIT: My question is different from the one linked above, since I'm looking for a compiler warning/error message to force me NOT to assign any static global variable to another static variable. I basically want to be forced by the compiler to avoid the whole fiasco. I'm wondering if that's possible.
I don't think you can throw an error automatically.
I've had issues like that, and here's what I've done to fix them. You can add some global bool globalStaticsDone variable that's set to false at compile time, and on entry to main you need to set that variable to true.
Then, if you have some code anywhere that you suspect gets called from global ctors you spice it up with assert(globalStaticsDone) (or c++ throws if you prefer) to catch unexpected uses of of these objects. Then, you go and fix these uses.
In general, in complex projects that's a common problem, where some non-trivial objects are created as global statics and end up using some other globals that might not have been initialized yet. Problem gets worse if your project is cross platform and order of compilation and linking is different on your target platforms. For example on ios and android builds might have these differences: in such cases it might be undefined behavior on one build and ok on another leading to some mysterious errors.
As an alternative, some compilers might offer uninitialized read checks in debug builds.

How can I declare variables with illegal names (such as "int double = 0")?

I have tried to do this but I'm unable. How can i declare a number of variables with legal and illegal names (such as int double = 0;), so that you can see how the compiler reacts.
The short answer to this is DON'T DO IT.
There are a number of reserved words in the C and C++ standards that should not be used for any purpose other than which they are originally intended. Going out of your way to recycle these for your own perverse purpose is going to create problems for a lot of people. One of those people might be yourself fin the future when you have to fix a bug.
If you want to use double as a variable name, the best method to make this happen is to successfully petition the C++ committee constructing the next standard to allow it. Then you will have a valid program.
If you want to see how the compiler behaves when encountering this problem, create tiny programs that are as small as practical. For example:
// invalid_double.c
int double = 0;
You'll immediately see a syntax error when trying to compile that. Repeat as necessary with other keywords. This is often how things like configure run tests to verify the behaviour and capabilities of the local compiler.
Your compiler will probably halt compilation at the first invalid use of a keyword so you may need to construct one file per experiment. Subsequent errors in the same file may be ignored, such as if you had int class = 0
it is like a Quote from (Programming__Principles_and_Practice_Using C++),I think the auther asks us to try it and see the error no more(just we try it ourselfes).

Why is there no warning when I write an empty main?

If I write a program like the following one, g++ and visual studio have the courtesy of warning me that the local variable a is never used :
int main()
{
int a; // An unused variable? Warning! Warning!
}
If I remove the unused variable (to make the compiler happy), it leaves me with the following program :
int main()
{
// An empty main? That's fine.
}
Now, I am left with a useless program.
Maybe I am missing something, but, if an unused variable is bad enough to raise a warning, why would an empty program be ok?
The example above is pretty simple. But in real life, if I have a big program with an empty main (because I forgot to put anything in it). Then having a warning should be a good thing, isn't it.
Maybe I am missing an option in g++ or visual studio that can raise a warning/error when the main is empty?
The reason for this is simple, if there is no return statement in main it implicitly returns EXIT_SUCCESS, as defined by the standard.
So an empty main is fine, no return needed, no function calls needed, nothing.
To answer the question why GCC doesn't warn you is because warnings are there to help you with common mistakes. Leaving a variable unused can lead to confusing errors, and code bloat.
However forgetting entirely to write a main function isn't a common mistake by anything but a beginner and isn't worth warning about (because it's entirely legal as well).
I suspect a lot of it is that compilers generally try to warn about things that are potential problems, but aren't necessarily apparent.
Now it's certainly true that if all your main contains a definition of a variable that's never used, that's fairly apparent -- but if you've defined 16 variables (or whatever) and one of them is no longer used, that may not be so obvious.
In the case of main containing nothing, I suppose the same could happen with an empty main -- for example, you could have a whole web of #ifdef/#elif/etc., that led to main being entirely empty for some particular platform. I'm pretty sure I've never run across this though, and I'm pretty sure I've never heard of anybody else seeing it either. At least to me, that suggests that it probably doesn't arise often enough in practice for most people to care much about the possibility.
if an unused variable is bad enough to raise a warning, why would an empty program be ok?
First of all, an empty main does not equal an empty program. There could be static objects with non-trivial constructors/destructors. These would get invoked irrespective of whether main is empty.
Secondly, one could think of lots and lots of potential errors that a compiler could warn about, but most compilers don't. I think this particular one doesn't come up very often (and takes seconds to figure out). I therefore don't see a compelling case for specifically diagnosing it.
When I was cleaning up inherited C code that comprised the customized runner for Informix 4GL, I fixed every warning having set the warning flag to catch everything, and there were lots of warnings.
I haven't used Visual C++ in a long time. Can't VC++ be configured to flag the most severe warnings? It is probably not the default setting, but one you have to change.
It is possible then that at least the unused variable would be flagged.
In a global sense int main() is just a definition of the main function of the program which returns SUCCESS when finishes.
The main function is the point by where all C++ programs start their execution, independently of its location within the source code.
So this:
int main()
{
// An empty main? That's fine.
// notice that the "return 0;" part is here by default, whether you wrote it or not
}
is just a definition of a function which returns admissible value.
So everything is ok, that's why the compiler is silent.

Function and declaring a local variable

Just having an conversation with collegue at work how to declare a variables.
For me I already decided which style I prefer, but maybe I wrong.
"C" style - all variable at the begining of function.
If you want to know data type of variable, just look at the begining of function.
bool Foo()
{
PARAM* pParam = NULL;
bool rc;
while (true)
{
rc = GetParam(pParam);
... do something with pParam
}
}
"C++" style - declare variables as local as possible.
bool Foo()
{
while (true)
{
PARAM* pParam = NULL;
bool rc = GetParam(pParam);
... do something with pParam
}
}
What do you prefer?
Update
The question is regarding POD variables.
The second one. (C++ style)
There are at least two good reasons for this:
This allow you to apply the YAGNI principle in the code, as you only declare variable when you need them, as close as possible to their use. That make the code easier to understand quickly as you don't have to get back and forth in the function to understand it all. The type of each variable is the main information about the variable and is not always obvious in the varaible name. In short : the code is easier to read.
This allow better compiler optimizations (when possible). Read : http://www.tantalon.com/pete/cppopt/asyougo.htm#PostponeVariableDeclaration
If due to the language you are using you are required to declare variables at the top of the function then clearly you must do this.
If you have a choice then it makes more sense to declare variables where they are used. The rule of thumb I use is: Declare variables with the smallest scope that is required.
Reducing the scope of a variable prevents some types errors, for example where you accidentally use a variable outside of a loop that was intended only to be used inside the loop. Reducing the scope of the variable will allow the compiler to spot the error instead of having code that compiles but fails at runtime.
I prefer the "C++ style". Mainly because it allows RAII, which you do in both your examples for the bool variable.
Furthermore, having a tight scope for the variable provides the compile better oppertunities for optimizations.
This is probably a bit subjective.
I prefer as locally as possible because it makes it completely clear what scope is intended for the variable, and the compiler generates an error if you access it outside the intended useful scope.
This isn't a style issue. In C++, non-POD types will have their constructors called at the point of declaration and destructors called at the end of the scope. You have to be wise about selecting where to declare variables or you will cause unnecessary performance issues. For example, declaring a class variable inside a loop may not be the wisest idea since constructor/destructor will be called every iteration of the loop. But sometimes, declaring class variables at the top of the function may not be the best if there is a chance that variable doesn't get used at all (like a variable is only used inside some 'if' statement).
I prefer C style because the C++ style has one major flaw to me: in a dense function it is very hard on eyes to find the declaration/initialization of the variable. (No syntax highlighting was able yet to cope reliably and predictably with my C++ coding hazards habits.)
Though I do adhere to no style strictly: only key variables are put there and most smallish minor variables live within the block where they are needed (like bool rc in your example).
But all important key variables in my code inevitably end up being declared on the top. And if in a nested block I have too much local variables, that is the sign that I have to start thinking about splitting the code into smaller functions.

why a variable declared but not used may cause a error?

If i declare a variable but not use it later in the program, the complier will give me a warning, and since "every warning should not be ignored", why the warning is there? and how can it cause a error? thanks!
First, a minor point: declaring a variable that's never used is a waste of memory, and thus is itself a bug.
Second, and more importantly: you took the trouble of writing out a declaration for a variable you then never used. Since you would not have bothered to declare a variable if you had no plan to use it, this suggests you've forgotten to use it! Is it possible you typed the wrong variable name in its place? Is it possible you forgot to perform a critical calculation whose result you'd store in that variable?
Of course, you might just have declared something you ended up not needing, which is why it's a warning and not an error, but it's easy to see situations where that warning can point you to an important piece of missing code, which would indeed be a bug.
It's there because maybe you meant to use the variable. You generally don't declare a variable and then use not it :)
It's a helpful warning, and it exists in most languages.
It may assist in detecting typos, where you accidentally used another variable instead of the one you meant to, this warning will remind you of the one that you haven't used :)
It doesn't cause an error. It causes a warning (normally only at higher levels on most compilers) because the variable isn't doing anything, which might indicate that you intended to use it but didn't. Sometimes that might indicate that your code is behaving incorrectly.
It's not that the code could fail as it is, just that the compiler's trying to warn you that you've done something a little odd.
It may indicate the presence of a bug, a variable that is declared but unused is obviously a programming error, since why else would it be there at all?
Are you asking about something like this?
int function() {
double x;
return 42;
}
There's a warning saying the variable x is unused because, well, it's unused. It is a warning because if a variable is unused, it does nothing*.
You may fall into this warning if you mistype or accidentally shadow a variable. For instance:
void printArgument10Times(int i) {
for(int i = 0; i < 10; ++i) {
std::cout << i << std::endl;
}
}
// ...
printArgument10Times(42);
Instead of printing 42 ten times, it prints 0 through 9. i was shadowed and was also unused. The compiler will hopefully tell you both these things.
*In C++ constructors and deconstructors are called, of course.