C++: Uninitialised Variable Passed as a Parm

G

Gene Wirchenko

Is the following guaranteed safe?

void InitInt(int & SomeInt)
{
SomeInt=3;
return;
}

int main()
{
int MainInt; // not initialised!
InitInt(MainInt);
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialise its parm, so why
bother initialising it first in main()? Unless, of course, it is not
safe. Is it safe?

Sincerely,

Gene Wirchenko
 
G

Gene Wirchenko

Is the following guaranteed safe?

Oops! I forgot to
#include said:
void InitInt(int & SomeInt)
{
SomeInt=3;
return;
}

int main()
{
int MainInt; // not initialised!
InitInt(MainInt);
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialise its parm, so why
bother initialising it first in main()? Unless, of course, it is not
safe. Is it safe?

Sincerely,

Gene Wirchenko
 
C

Chris Theis

Gene Wirchenko said:
Oops! I forgot to

In principle it´s safe though the practice itself is arguable - why not
initialize at the point of declaration?
To see whether it makes sense you´d need to provide some more details of
your intention.

Chris
 
L

Le Géant Vert

Gene Wirchenko said:
Oops! I forgot to


Sincerely,

Gene Wirchenko

sounds perfectly safe to me... nevertheless, I hardly understatnd the point
of this function : costs a function call and does almost nothing
interesting... and you don't need the return in the function InitInt.
 
T

tom_usenet

Is the following guaranteed safe?

void InitInt(int & SomeInt)
{
SomeInt=3;
return;
}

int main()
{
int MainInt; // not initialised!
InitInt(MainInt);
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialise its parm, so why
bother initialising it first in main()? Unless, of course, it is not
safe. Is it safe?

Yes - you don't convert MainInt to an rvalue until after you've given
it a valid value.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 
V

Victor Bazarov

Le Géant Vert said:
sounds perfectly safe to me... nevertheless, I hardly understatnd the point
of this function : costs a function call and does almost nothing
interesting... and you don't need the return in the function InitInt.

Gene probably provided the simple function just for illustration purposes.
The point is that if you pass an uninitialised object by reference, some
compilers complain (with a warning, of course), often such warning is not
necessarily founded. That's all.

Victor
 
G

Gene Wirchenko

On Wed, 17 Dec 2003 19:39:13 +0100, "Le Géant Vert"

[snip]
sounds perfectly safe to me... nevertheless, I hardly understatnd the point
of this function : costs a function call and does almost nothing
interesting... and you don't need the return in the function InitInt.

Thank you. As to the nit:

Oh, come off it! I posted a small program that illustrated my
point. It is called an example. If the initialisation function had
included code to initialise a 79 TB structure, it would not have made
the point any better (and would probably have obscured it).

Sincerely,

Gene Wirchenko
 
G

Gene Wirchenko

On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
[snip]
The intent of the function is to initialise its parm, so why
bother initialising it first in main()? Unless, of course, it is not
safe. Is it safe?

Yes - you don't convert MainInt to an rvalue until after you've given
it a valid value.

Thank you.

Yes, very deliberately so.

(I have encountered languages where this would not be safe.)

Sincerely,

Gene Wirchenko
 
E

E. Robert Tisdale

Gene said:
Is the following guaranteed safe?

void InitInt(int & SomeInt) {
SomeInt=3;
return;
}

This is poor programming practice. The following:

int InitInt(void) {
return 3;
}

would be much better.
int main(int argc, char* argv[]) {
int MainInt; // not initialized!
InitInt(MainInt);

int MainInt = InitInt();

You should *always* try to avoid uninitialized variables.
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialized its parm, so why
bother initializing it first in main()? Unless, of course, it is not
safe. Is it safe?

It is *dangerous* because the variable may be used uninitialized.
If not by you, then by some poor programmer who must maintain your code.
Good programming habits will help keep you out of trouble.
 
J

jeffc

Gene Wirchenko said:
On Wed, 17 Dec 2003 19:39:13 +0100, "Le Géant Vert"

[snip]
sounds perfectly safe to me... nevertheless, I hardly understatnd the point
of this function : costs a function call and does almost nothing
interesting... and you don't need the return in the function InitInt.

Thank you. As to the nit:

Oh, come off it! I posted a small program that illustrated my
point. It is called an example.

Now I think you understand why I object when people post "answers" that are
off the topic of the original question. Interesting :)
 
K

Karl Heinz Buchegger

jeffc said:
Now I think you understand why I object when people post "answers" that are
off the topic of the original question. Interesting :)

There is a difference between posting an otherwise valid program which
just demonstrates an idea and a program which contains a bug unnoticed
by the poster.
 
G

Gene Wirchenko

This is poor programming practice. The following:

int InitInt(void) {
return 3;
}

would be much better.

No, because this is only an example of initialisation. For an
arbitrarily complex initialisation, there might be more than one parm
being initialised and in such configuration that it could not be
combined into one structure and thus would not be suitable for a
return value.
int main(int argc, char* argv[]) {

I did not write the above line. I wrote:
int main()
int MainInt = InitInt();

You should *always* try to avoid uninitialized variables.

That is why I call an initialisation routine.
It is *dangerous* because the variable may be used uninitialized.
If not by you, then by some poor programmer who must maintain your code.
Good programming habits will help keep you out of trouble.

Initialising a variable twice is unclear. I try to avoid such
confusions. Given a complex initialisation, I would note where the
initialisation was dealt with.

Sincerely,

Gene Wirchenko
 
E

E. Robert Tisdale

Gene said:
No, because this is only an example of initialisation.
For an arbitrarily complex initialisation,
there might be more than one parameter being initialised
and in such configuration that
it could not be combined into one structure
and thus would not be suitable for a return value.


That is why I call an initialisation routine.

You should avoid any initialization routine except, perhaps,
a private class member function to be called by a constructor.
A method which is applied to an object after construction
is a *modifier* and *not* an initializer.
A *modifier* changes the object's *state*.
You should try to design your classes
so that objects can be declared const
and initialized at the point where they are declared.
This minimizes the number of variables
that you need to keep track of in your program
which makes your program easier for you and other programmers
to read, understand and maintain.
Container classes are an obvious exception.
You can't do much with a const container.
Initialising a variable twice is unclear.

I try to avoid such confusions. Given a complex initialisation,
I would note where the initialisation was dealt with.

The best place to deal with [complicated] initialization
is in a constructor. Subscribers to the comp.lang.c++ newsgroup
can help you with designing constructors
to completely initialize complicated objects.
 
J

Jason Heyes

E. Robert Tisdale said:
Gene said:
Is the following guaranteed safe?

void InitInt(int & SomeInt) {
SomeInt=3;
return;
}

This is poor programming practice. The following:

int InitInt(void) {
return 3;
}

would be much better.
int main(int argc, char* argv[]) {
int MainInt; // not initialized!
InitInt(MainInt);

int MainInt = InitInt();

You should *always* try to avoid uninitialized variables.
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialized its parm, so why
bother initializing it first in main()? Unless, of course, it is not
safe. Is it safe?

It is *dangerous* because the variable may be used uninitialized.
If not by you, then by some poor programmer who must maintain your code.
Good programming habits will help keep you out of trouble.

The fact of the matter is that MainInt *is* initialised, albeit to a
meaningless value. What makes it bad practice is not that the initial value
of MainInt is meaningless, but rather that the initial value of MainInt is
never used. It is overwritten with a new value by InitInt(). Doesn't this
spell bad programming practice?
 
J

Jack Klein

E. Robert Tisdale said:
Gene said:
Is the following guaranteed safe?

void InitInt(int & SomeInt) {
SomeInt=3;
return;
}

This is poor programming practice. The following:

int InitInt(void) {
return 3;
}

would be much better.
int main(int argc, char* argv[]) {
int MainInt; // not initialized!
InitInt(MainInt);

int MainInt = InitInt();

You should *always* try to avoid uninitialized variables.
std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialized its parm, so why
bother initializing it first in main()? Unless, of course, it is not
safe. Is it safe?

It is *dangerous* because the variable may be used uninitialized.
If not by you, then by some poor programmer who must maintain your code.
Good programming habits will help keep you out of trouble.

The fact of the matter is that MainInt *is* initialised, albeit to a

No, it is not. Not in the terms defined by the C++ standard. It is
uninitialized and might indeed contain a trap representation, that is
a bit pattern that does not represent a valid value for the object
type.
meaningless value. What makes it bad practice is not that the initial value
of MainInt is meaningless, but rather that the initial value of MainInt is
never used. It is overwritten with a new value by InitInt(). Doesn't this
spell bad programming practice?

There is no initial value to be unused. An uninitialized object has
indeterminate. Any use of an indeterminate value produces undefined
behavior.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jason Heyes

Jack Klein said:
E. Robert Tisdale said:
Gene Wirchenko wrote:

Is the following guaranteed safe?

void InitInt(int & SomeInt) {
SomeInt=3;
return;
}

This is poor programming practice. The following:

int InitInt(void) {
return 3;
}

would be much better.


int main(int argc, char* argv[]) {
int MainInt; // not initialized!
InitInt(MainInt);

int MainInt = InitInt();

You should *always* try to avoid uninitialized variables.

std::cout << MainInt << std::endl;
return 0;
}

The intent of the function is to initialized its parm, so why
bother initializing it first in main()? Unless, of course, it is not
safe. Is it safe?

It is *dangerous* because the variable may be used uninitialized.
If not by you, then by some poor programmer who must maintain your code.
Good programming habits will help keep you out of trouble.

The fact of the matter is that MainInt *is* initialised, albeit to a

No, it is not. Not in the terms defined by the C++ standard. It is
uninitialized and might indeed contain a trap representation, that is
a bit pattern that does not represent a valid value for the object
type.
meaningless value. What makes it bad practice is not that the initial value
of MainInt is meaningless, but rather that the initial value of MainInt is
never used. It is overwritten with a new value by InitInt(). Doesn't this
spell bad programming practice?

There is no initial value to be unused. An uninitialized object has
indeterminate. Any use of an indeterminate value produces undefined
behavior.

Oh well in that case it is simply wrong code. I wasn't aware that the C++
standard was so strict with regard to initialised variables. Personally I
never declare an object without initialising it - no matter what type it is.
But let me ask you, does assigning a value to an uninitialised int result in
undefined behavior? Thanks.
 
T

tom_usenet

Oh well in that case it is simply wrong code. I wasn't aware that the C++
standard was so strict with regard to initialised variables. Personally I
never declare an object without initialising it - no matter what type it is.
But let me ask you, does assigning a value to an uninitialised int result in
undefined behavior? Thanks.

No. Only using an indeterminate value as an rvalue is undefined
behaviour. Using is as an lvalue (in, say, an assignment or binding to
a reference as in the OP's code) is fine.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 
G

Greg Comeau

Oh well in that case it is simply wrong code. I wasn't aware that the C++
standard was so strict with regard to initialised variables.

As is C.
Personally I
never declare an object without initialising it - no matter what type it is.

That's a very good rule of thumb, but if I'm understanding you,
forcing an initialization can often be awkward.
But let me ask you, does assigning a value to an uninitialised int result in
undefined behavior? Thanks.

No, because that's not a use of the indeterminate value.
 
E

E. Robert Tisdale

Greg said:
That's a very good rule of thumb, but if I'm understanding you,
forcing an initialization can often be awkward.

Not very often
but I'll give an example where it is awkward -- containers:

int a[n];
for (int j = 0; j < n; ++j)
cin >> a[n];

Unless they are small, const containers can be awkward to initialize:

const int a[] = {0, 1, 2, 3};

Well, you get the idea. You can do this:

class wrapper {
private:
int a[n];
public:
const
int& operator[](int j) const { return a[j]; }
int& operator[](int j) { return a[j]; }
wrapper(std::istream& is) {
for (int j = 0; j < n; ++j)
is >> a[n];
}
};

then this:

const wrapper a(cin);

Of course, this can cause a problem,
if the constructor encounters an exception while reading from cin.
Is this awkward? Problematic?
I suspect that you would say yes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top