Initialising Variables

D

DaveC

I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

Your thoughts on the above would be welcome (as an aside), but my main
problem follows.

Now I've recently upgraded to gcc 4, and I find I'm missing the compiler
warnings I used to get on gcc 3 regarding uninitialized vars (the warning
flags -Wall, etc., are still there, I just don't get the warning messages).

Consider the code below. I expected to get a warning about foo being
uninitialized, but I don't. I'm sure there's a simple explanation, but I
can't see it.

int
main(void)
{
int foo;
int i;

i = 0;
while (i) {
if (i == 10) {
foo = 50;
}

if (foo) {
printf("%d\n", foo);
}

++i;
if (i > 20) {
break;
}
}


return 0;
}
 
M

mark_bluemel

DaveC said:
I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

I don't believe the standard states that compilers have to produce
warnings for this.
Your thoughts on the above would be welcome (as an aside), but my main
problem follows.

Now I've recently upgraded to gcc 4, and I find I'm missing the compiler
warnings I used to get on gcc 3 regarding uninitialized vars (the warning
flags -Wall, etc., are still there, I just don't get the warning messages)

This is now a question about the GCC compiler, not about the C
language. This is probably not the ideal newsgroup in which to ask such
as question.

<Off-topic>
Two minutes on the GCC webpages yielded
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Warning-Options.html#Warning-Options
and the -Wuninitialized option which is enabled by "-Wall", but depends
on -O1 (at least).
</Off-topic>
 
D

DaveC

This is now a question about the GCC compiler, not about the C
language. This is probably not the ideal newsgroup in which to ask such
as question.

<Off-topic>
Two minutes on the GCC webpages yielded
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Warning-Options.html#Warning-Options
and the -Wuninitialized option which is enabled by "-Wall", but depends
on -O1 (at least).
</Off-topic>


Yeah, I realised I was in danger of being off topic, but thanks for the
response anyway. For the record, those warning flags were used, as was
the optimization :(
 
M

Mark F. Haigh

DaveC said:
I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

Your thoughts on the above would be welcome (as an aside), but my main
problem follows.

Now I've recently upgraded to gcc 4, and I find I'm missing the compiler
warnings I used to get on gcc 3 regarding uninitialized vars (the warning
flags -Wall, etc., are still there, I just don't get the warning messages).

This is really not the place; ask in a gcc-specific newsgroup or
mailing list.
Consider the code below. I expected to get a warning about foo being
uninitialized, but I don't. I'm sure there's a simple explanation, but I
can't see it.

int
main(void)
{
int foo;
int i;

i = 0;
while (i) {
if (i == 10) {
foo = 50;
}

if (foo) {
printf("%d\n", foo);
}

++i;
if (i > 20) {
break;
}
}


return 0;
}

Your entire while loop is dead code. Current gccs do a DCE (dead code
elimination) pass before the data flow analysis pass, which is the pass
that produces the uninitialized variable warnings.

Back somewhat on-topic, note that C compilers are __not__ required to
detect or diagnose this issue. It's a quality of implementation, or
QoI, issue. The gcc developers choose to make a best effort to warn
the user, and they only do it for non-dead code that will be present in
the output binary. This avoids wasting non-trivial amounts of time
analyzing code that will never even exist in the output binary.

Change the code to i = 1, compile again, and see what you get.

Mark F. Haigh
(e-mail address removed)
 
C

Chris Dollin

DaveC said:
I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

Didn't we have a warlet about this a while ago?

My position is this: variables should be initialised when declared, with
their sensible initial values. (ie, don't declare a variable until you
have its value in hand.)

Sometimes you can't do this. Then either leave the variable uninitialised,
or initialise it to a safe dummy value, as seems most clear in that
variable's environment, or shake the design hard to see if something
rattles: maybe fixing it will let you get back to declare-when-ready.

Reasonable people may differ. (Since I'm not a reasonable person, I
don't have to believe that.)
 
D

DaveC

Change the code to i = 1, compile again, and see what you get.

Thanks Mark, I realised my mistake as soon as I posted, but it makes no
difference, the result is the same.
 
M

Mark F. Haigh

DaveC said:
Thanks Mark, I realised my mistake as soon as I posted, but it makes no
difference, the result is the same.

[mark@icepick clc]$ gcc -Wall -W -ansi -pedantic -O2 -o foo foo.c
foo.c: In function 'main':
foo.c:8: warning: 'foo' may be used uninitialized in this function

Both gcc 4.x and 3.2.x produce this warning. Most likely you forgot
-O2. Again, if you're going to use gcc, you're going to have to read
the documentation eventually, and there's no time like the present.


Mark F. Haigh
(e-mail address removed)
 
R

Richard Heathfield

DaveC said:
I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

Except that they don't always manage it, as you just discovered. So your
colleagues are wrong to say it's bad practice. Some people (such as myself)
actually consider it good practice.
 
D

DaveC

DaveC said:
Thanks Mark, I realised my mistake as soon as I posted, but it makes no
difference, the result is the same.

[mark@icepick clc]$ gcc -Wall -W -ansi -pedantic -O2 -o foo foo.c
foo.c: In function 'main':
foo.c:8: warning: 'foo' may be used uninitialized in this function

And that's exactly the result I was expecting. Unfortunately I don't get
that (even when I copy/paste your exact line) :( I've been scouring the
gcc manual all morning and everything suggests it should do what yours did
(and what mine used to).

Oh well, looks like I probably have deeper problems. Thanks for the help,
at least I know I'm not going mad now.
 
M

Mark F. Haigh

DaveC said:
DaveC said:
On Mon, 22 Jan 2007 03:31:16 -0800, Mark F. Haigh wrote:

Change the code to i = 1, compile again, and see what you get.

Thanks Mark, I realised my mistake as soon as I posted, but it makes no
difference, the result is the same.

[mark@icepick clc]$ gcc -Wall -W -ansi -pedantic -O2 -o foo foo.c
foo.c: In function 'main':
foo.c:8: warning: 'foo' may be used uninitialized in this function

And that's exactly the result I was expecting. Unfortunately I don't get
that (even when I copy/paste your exact line) :( I've been scouring the
gcc manual all morning and everything suggests it should do what yours did
(and what mine used to).

Oh well, looks like I probably have deeper problems. Thanks for the help,
at least I know I'm not going mad now.

That's with the code in foo.c changed to i = 1, for the record. With i
= 0, no warnings will be output, for reasons already discussed.

Mark F. Haigh
(e-mail address removed)
 
Y

Yevgen Muntyan

DaveC said:
I always used to initialise variables at declaration, then a couple of
colleagues started telling me it was bad practice and that the compiler
should be left to spot the use of uninitilised variables and hence
possible bugs.

You should not initialize variables to catch uninitialized varaibles?
Kind of strange. It seems I understand what they mean, but it's stupid
if it's correct (they are saying not to initialize foo to 0 to make sure
it's initialized later to correct 8 or 42) - compiler may be of great
help but it's not as good as it should (i.e. it's not ideal).
Your thoughts on the above would be welcome (as an aside), but my main
problem follows.

Now I've recently upgraded to gcc 4, and I find I'm missing the compiler
warnings I used to get on gcc 3 regarding uninitialized vars (the warning
flags -Wall, etc., are still there, I just don't get the warning messages).

Consider the code below.

[snip]

After fixing it up, gcc-4.1.2 does what you're saying here, while
gcc-3.4.2 emits desired warning. Interesting thing is that it's some
kind of optimization - printf shows that gcc initializes foo once
(and standard doesn't forbid this so it's not a bug). If you add
some 'if (i == 15) foo = 52;' then the warning comes back.
Could you file a bug report? It's not strictly a bug, but old
behavior was way more useful than it's now, maybe it's not expensive
to get it back.

Best regards,
Yevgen
 
D

DaveC

After fixing it up, gcc-4.1.2 does what you're saying here, while
gcc-3.4.2 emits desired warning. Interesting thing is that it's some
kind of optimization - printf shows that gcc initializes foo once
(and standard doesn't forbid this so it's not a bug). If you add
some 'if (i == 15) foo = 52;' then the warning comes back.
Could you file a bug report? It's not strictly a bug, but old
behavior was way more useful than it's now, maybe it's not expensive
to get it back.

Bug report raised, I'll see what the gcc experts make of it. Nice to see
you got the same results though, I thought I was going mad there for a
minute.
 
C

CBFalconer

Richard said:
DaveC said:


Except that they don't always manage it, as you just discovered.
So your colleagues are wrong to say it's bad practice. Some people
(such as myself) actually consider it good practice.

Whee - style war.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
C

CBFalconer

DaveC said:
Bug report raised, I'll see what the gcc experts make of it. Nice to see
you got the same results though, I thought I was going mad there for a
minute.

You obviously didn't read the responses in this thread. It was
pointed out that it was not a bug, but the innate consequence of
your test code.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
R

Richard Tobin

Yevgen Muntyan said:
You should not initialize variables to catch uninitialized varaibles?
Kind of strange. It seems I understand what they mean, but it's stupid
if it's correct (they are saying not to initialize foo to 0 to make sure
it's initialized later to correct 8 or 42)

The idea is not to initialise variables to values you're not going to
use. If you going to set x later on, when you have the data ready to
calculate it, you shouldn't set it to 0 when you declare it. That
way, if you mistakenly fail to set it when you ought to, the compiler
may spot the mistake, but if it's already set to 0 at declaration the
compiler can't tell that.

Initialising a variable to a value that you're not going to use is
lying to the compiler. You're telling it "this variable should be
zero (or whatever) and is safe to use" when in fact there's no value
that it should have and it should not be used. Lying to the compiler
is sometimes useful if, for example, it produces spurious warnings,
but I recommend avoiding it as far as possible.

-- Richard
 
D

DaveC

You obviously didn't read the responses in this thread. It was
pointed out that it was not a bug, but the innate consequence of
your test code.

I read it, I just misunderstood the statement to mean raise a bug anyway.

The result of raising the bug lead to a few more pointers to dupes of the
same and related bugs, so it appears the gcc developers do indeed consider
it a bug!
 
K

Kenny McCormack

CBFalconer said:
You obviously didn't read the responses in this thread. It was
pointed out that it was not a bug, but the innate consequence of
your test code.

Nope. It is you who didn't read for comprehension (a general failing of
yours).

It's been determined that even after changing the: if (0)
to: if (1)

It still generates no warning under gcc 4. The exact same code and
command line *does* generate a warning under gcc 3.

Better luck next time!
 
C

christian.bau

Yevgen said:
After fixing it up, gcc-4.1.2 does what you're saying here, while
gcc-3.4.2 emits desired warning. Interesting thing is that it's some
kind of optimization - printf shows that gcc initializes foo once
(and standard doesn't forbid this so it's not a bug). If you add
some 'if (i == 15) foo = 52;' then the warning comes back.
Could you file a bug report? It's not strictly a bug, but old
behavior was way more useful than it's now, maybe it's not expensive
to get it back.

The optimizer has effectively replaced code invoking undefined behavior
with code invoking arbitrary defined behavior. This is no improvement
(in most implementations, not initializing foo has exactly the same
effect as setting it to an arbitrary value anyway), so there is no
reason to remove the warning. So it is definitely a bug (not as far as
the C Standard is concerned, but as far as users of gcc are concerned).
 
R

Richard Heathfield

CBFalconer said:
Whee - style war.

Unlikely. The people in this group whose opinions I value and yet which
differs from mine are... people whose opinions I value. And those who agree
with me... agree with me. I'm not about to try to go to war with either
group, and I don't think they are either.

It's possible for people to hold different opinions about a subject
*without* trying to kill each other. :)
 
R

Richard Heathfield

Richard Tobin said:

Initialising a variable to a value that you're not going to use is
lying to the compiler.

I disagree. I consider it a sensible safety precaution.

Obviously your mileage varies, and I respect your reasons, but other
reasonable views exist.
 

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,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top