user3370603
user3370603

Reputation: 87

Unexpected output for integer values used as counter

While writing what should be a very simple program ( out of K&R C book ), I get some output which I do not understand. If I EOF right away, nl_count is correctly 0, but space_count is always 32767 ( half of maximum int range), and tab_count is a large value ( usually very high or very low ).

When I initialize all variables to 0, then the program works correctly. What am I missing here?

 10 int main(void)
 11 {
 12         int tab_count, space_count, nl_count;
 13 
 14         //tab_count = space_count = nl_count = 0;
 15 
 16         int c;
 17         while( (c = getchar()) != EOF ){
 18                 if( c == '\t' )
 19                         tab_count++;
 20                 if( c == ' ' )
 21                         space_count++;
 22                 if( c == '\n' )
 23                         nl_count++;
 24         }
 25 
 26         printf("\n");
 27         printf("TABS = %d\n", tab_count);
 28         printf("SPACES = %d\n", space_count);
 29         printf("NEWLINES = %d\n", nl_count);
 30 
 31         return 0;
 32 }

Inputs and Outputs:

Here is another input, which again correctly outputs 3 for newlines, but junk for tabs, and 32767 for spaces.

(space)(space)(space)\t\t\t\n\n\n

TABS = 441446448
SPACES = 32767
NEWLINES = 3

Upvotes: 1

Views: 81

Answers (4)

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

The problem here is, when you define automatic local variables, they are not initialized to any value implicitly. You have to initialize them explicitly. Otherwise, the content of those variables are garbage and indeterminate.

Reference: C11, chapter §6.7.9, Initialization

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

Next, without a write (atleast, the initialization), if you try to use (read) the value, it invokes undefined behaviour.

Reference: C11, Annex §J.2

The value of an object with automatic storage duration is used while it is indeterminate

Then, to answer

When I initialize all vars to 0, then the program works correctly

Yes, ofcourse, because, that way, there is no UB.

So, in your code, you have to change

 int tab_count, space_count, nl_count;

to

 int tab_count = 0;
 int space_count = 0;
 int nl_count = 0;

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227370

When I initialize all vars to 0, then the program works correctly. What am I missing here?

tab_count, space_count and nl_count; are automatic storage variables. If you don't initialize them to 0, they have a indeterminate values. Reading from them is technically undefined behaviour (UB). Since you're incrementing their value before initializing them, you are invoking UB. One manifestation of UB is to produce seemingly nonsensical values.

Upvotes: 5

Abhishek
Abhishek

Reputation: 2945

Only Extern and Static variables are initialized to 0 by default. All other variables have an indeterminate value, which is why you have to initialize them to 0 before using them.

Upvotes: 3

john
john

Reputation: 87944

I can't resist.

When I initialize all vars to 0, then the program works correctly. What am I missing here?

You are missing that you must initialise all the variables to zero.

Maybe what you are really missing is the fact that C programs that break the rules can have undefined/unspecified behaviour. This mean they can appear to work, or partially work, even though they are incorrect.

Upvotes: 2

Related Questions