What is the best way to catch unitialized variables?

Sometimes the compiler catches these for you,
but are there techniques or coding disciplines that
decrease the chance that these will slip through?

Ken
P.S.  I already commpile with -Wall
klopterAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chensuCommented:
Use assert.
0
nietodCommented:
Use constructors in EVERY class you write that initialize EVERY data member.  The penaltiy in size and speed due to unneccessary initializations will usually be very slight, the benefits in terms of programmer's hair loss....
0
nietodCommented:
avoid using ordinary C pointers and arrays directly.  Instead use C++ classes that encapsulate these, like smart pointers, and container classes like vector<>
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

klopterAuthor Commented:
nietod I think that your answer (using container
classes like vector<>) is probably the answer not
just to this question but also to my other question:

http://www.experts-exchange.com/jsp/qShow.jsp?ta=cplusprog&qid=10260303 

In that question I post the following code.
If you can show me to convert this code to
use the vector<> class I will happily give you
the points for both questions.

Here is the code:

#include <fstream>

                 void subr() {
                   fstream *fout = new fstream[1];
                   fout[0].open("Afile", ios::out | ios::binary);
                   fout[0].close();
                 }




Thanks again,
  Ken
0
mikeblasCommented:
Initializing members isn't going to do much good, and seems like tautological advice to me.

Q: "How do I catch uninitalized variables?"
A: "Initialize all your variables."

Even if you initialize them, there's nothing that guarnatees the situation will be better. If you initialize a member pointer to zero, for instance, and just go ahead and dereference it without testing, you'll still crash.

If your compiler isn't catching everything, then you should consider using a lint tool that offers better diagnostics than your compiler.

If there are still some getting through, the bst tool at your disposal is aggressively doing peer reviews--hav your dev team get together and walk through the code in meetings. This helps education on the team substantially, and that in turn assures that component integration is smoother.

..B ekiM
0
nietodCommented:
>> the answer not just to this question but
>> also to my other question
Sorry, probably not.  The code is 100% legitimate C++.  It should work fine.  It however is not as robust as code that uses vector<>  (you have to remember to delete delete the array of fstream, you have to be careful to never go past the ends of the array of fstream.  With a vector, this stuff is automatic.)

anyways, you would do

#include <vector>

using namespace std; // Not necessary, but otherwise you
                             // have to specify "std::" a lot.

vector<fstream> fout;
fout.resize(1);
fout[0].open("Afile", ios::out | ios::binary);
fout[0].close();
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nietodCommented:
>> Even if you initialize them, there's nothing that
>> guarnatees the situation will be better
Not completely true.  If they are initialized they will work consistently. If a pointer is initialized to NULL it will always cause a crash if dereferenced without being reset.  However, if variables are not initialized, they are unpredictable.  You may find that the code works well for a time being and then crashes.  The most common cause of this is code that uses data that global and is later switched to local.  For example, if you develop a class that contains a pointer and don't initialize the pointer.  If you init8ially work with objects of the class that are global, the pointer iwll always be initialized to NULL.  If your code tests for this and uses it as a semaphore, which is common, that the code might work perfectly.   However, when you create a local copy of the object, the pointer is not initialized.  Then when code test for the NULL pointer it finds it might not be NULL--crash.  There are plenty of other cases like this too.
0
nietodCommented:
>> you should consider using a lint tool that
>> offers better diagnostics than your compiler
VC has some nice features for this.  It can initialize variables and allocated memory to OCh (or other specified values) to help spot uninitialized "things"  It also has great features for tracking mistakes in allocating and freeing memory.
0
klopterAuthor Commented:
nietod - First let me say that I agree that an
initialized variabel is better than an unititialized
variable even if it is initialized ot he wrong value or used inappropriately - at least you get consistent results.

I played around with your suggestion on how to use the vector class but with no success.  fout.resize
generates 59 error messages from gcc -Wall.
Here is the file cut down to the minimum:

#include <fstream>
#include <vector>

using namespace std;
void subr() {
                 vector<fstream> fout;
             fout.resize(1);
}

The first few error messages are:

/util/include/g++/stl_algobase.h: In function `class fstream * __copy_d<const fs
tream *, fstream *, long int>(const class fstream *, const class fstream *, clas
s fstream *, long int *)':
/util/include/g++/stl_algobase.h:122: warning: conversion from `const fstream' t
o `fstream &' discards const
/util/include/g++/fstream.h:90: warning: in passing argument 1 of `fstream::oper
ator =(fstream &)'
/util/include/g++/streambuf.h: In method `class fstreambase & fstreambase::opera
tor =(class fstreambase &)':



Begin daunted by these error messages , I
thought that perhaps I could still make progress
by avoiding resize, so I tried:

#include <fstream>
#include <vector>

using namespace std;
void subr() {
  vector<fstream> fout[1];
  fout[0].open("Afile", ios::out | ios::binary);
}


Which yielded the following error messages:

what2.cc: In function `void subr()':
what2.cc:7: no matching function for call to `vector<fstream,__default_alloc_tem
plate<false,0> >::open (char[6], int)'
what2.cc:6: warning: variable `class vector<fstream,__default_alloc_template<fal
se,0> > * this' might be clobbered by `longjmp' or `vfork'


The first error message suggests that it can't
find open() anymore.  The second is the error
message that prompted this entire thread.

The good news is that I am learning about C++
with your help.

Ken
0
klopterAuthor Commented:
Adjusted points to 200
0
chensuCommented:
>Use constructors in EVERY class you write that initialize EVERY data member.

But there are still chances to forget to initialize it. Not to mention you will still need a lot of auto variables. And you may also initialize it to a wrong value.


By using assert extensively, you can make sure that the code is running under the control of your brain. Using assert not only helps debugging but also helps you think about the logics of the program.
0
klopterAuthor Commented:
Thanks nietod

I'll give you the oitns on this one  and hoipe
to continue the discussion on the other.

Ken
0
mikeblasCommented:
klopter> First let me say that I agree that an
 klopter> initialized variabel [sic] is better than an unititialized
 klopter> variable even if it is initialized ot he wrong
 klopter> value or used  inappropriately -

I think we all agree on that. All that nietod was saying (in that one post) is that one way to avoid uninitialized variables is to initialize them all. I'm pointing out that's tautological, and still not going to find the error until runtime.

 nieotd> VC has some nice features for this.  

Unfortunately, klopter isn't using VC++.

 chensu> But there are still chances to forget to initialize it.

Which is why you need to approach this problem with very robust tools or with code reviews. The more eyes, the less chance. The more experienced eyes, the better knowledge transfer.

..B ekiM
0
nietodCommented:
I aggree with chensu about the liberal use of asserts, (and I use them a lot!) but the problem is that programmer use them to test for mistakes that they think of an not the mistakes they don't think of.  And the mistakes you don't think of always outnumumber the ones that you do.   That asside, asserts are very useful in detecting all sorts of problems, including uninitialized varaibles.

Mike, I aggree with what you are saying, but klopter also askes

>> are there techniques or coding disciplines that
>> decrease the chance that these will slip through?

Thus I think my "answer" qualifies as a technique to prevent these sorts of problems.  And while I think code reviews are a great practice, I find that in OO code they are poor at finding uninitialized class members (Especially if your code standards don't demand explicit initialization of all members)..  This is because the initialization of class members often occurs far from their use.  Code reviewers are often looking in intently at the little details and often fail to pick-up larger problems in design, like this.

klopter

vector's look like arrays in most ways, but not all.,

>> vector<fstream> fout[1];

won't work--news to you?  But

  vector<fstream> fout(1);

should.  However, it sounds like you have other problems.
0
nietodCommented:
I'm not sure why you are getting those warnings.  However, they are warnings about removing "const" so I think you may be okay.  It suggests that the STL author was a a little careless in how the code was written (or it was old code that needs to be rewritten for the C++ standard) so it is reporting potential errors that probalby are not errors.

The secodn set of error messages are because of the [1] you had on fout, remove that and you should only have warnings.
0
mikeblasCommented:
nietod> I find that in OO code they are poor at finding
 nietod> uninitialized class members

Then, you need to have more disciplined code reviews. Class members are all written down, and their initialziation patters are easily recognizable. You need to use those reviews to instil more disciplined techniques on your team.

C++ offers the ability to freely move variable initializations closer to where they're used. You should also instill that discipline.

 nietod> the liberal use of asserts

That doesn't find the problem at compile time, which is what klopter has asked about.

..B ekiM
0
nietodCommented:
>> That doesn't find the problem at compile time,
And can give a false sense of security as some areas of code might not be tested until the user does so on a release version.

>> C++ offers the ability to freely move variable
>> initializations closer to where they're used. You
>> should also instill that discipline.
In a class?  The data members have to be initialized in a constructor.  And the data members may be used outside of the constructor.  A clear set of invariants and pre- and post-conditions should prevent this from being a problem, but in practice people are lazy.  

>> You need to use those reviews to instil
>> more disciplined techniques on your team.
amen.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.