4

In C language, is

int x, y, z = 0;

the same as this?

int x = 0;
int y = 0;
int z = 0;

Also, if I just say int a;, it seems that the value of a is zero even if it is uninitialized, but not undefined as described in What will be the value of uninitialized variable?

Community
  • 1
  • 1
Ka Wa Yip
  • 2,546
  • 3
  • 22
  • 35

4 Answers4

5

No the two are not equivalent.

int x, y, z = 0;

In this line x and y will have indeterminate value, while z is initialized to zero.

You can however keep it in "one line" for the price of some verbosity:

int x = 0, y = x, z = y;

Now all three are initialized with the same value (the one you gave x). To initialize one variable with another, all that is required is for the initializer to be previously defined. And it works even if it's on the same line. The above will also allow you to change the initial value for all variable quite easily.

Alternatively, if you find the previous style ugly, you can make it work in two lines:

int x, y, z;
x = y = z = 0;

But it's now assignment, and not initialization.

Also, if I just say int a;, it seems that the value of a is zero even if it is uninitialized, but not undefined as described in What will be the value of uninitialized variable?

"Indeterminate value" doesn't mean "not-zero". There is nothing about zero that makes it an invalid candidate for the variables initial value. Some "helpful" compilers zero initialize variables in debug builds. It can hide sinister bugs if you don't also heed compiler warnings.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • `int x = 0, y = x, z = y;` really does look ugly and `x = y = z = 0;` is assignment not initialization. `int x = 0, y = 0, z = 0;` is clean and most preferred way. – haccks Jan 29 '17 at 08:14
  • @haccks - (*shurg*) okay. – StoryTeller - Unslander Monica Jan 29 '17 at 08:15
  • It is possibly more common for a *debug environment* to simply fill the stack with zero (or some other specific value) at start-up rather the compiler providing explicit initialisation, but I have by no means verified that assertion for all compilers/debuggers. – Clifford Jan 29 '17 at 08:56
  • this statement: `int a;` yields no specific value for `a` unless `a` is declared in the file global space. When declared on the stack, it will contain what ever garbage happened to be on that stack at that location (the chances of that being 0 is about 4gig: 1 against – user3629249 Jan 29 '17 at 18:14
4

This:

int x, y, z = 0;

is not the same as

int x = 0, y = 0, z = 0;

or

int x = 0;
int y = 0;
int z = 0;

In the first case only z will be initialized while in the latter two cases - all three.

If value is not initialized its value is indeterminate and reading uninitialized variable is undefined behavior - and the fact that after reading it it appears to have value 0 is result of undefined behavior.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
2

A statement like

 int x, y, z = 0;

only initializes the last variable, z; x and y remain uninitialized.

A possible equivalent of

int x = 0;
int y = 0;
int z = 0;

would be

int x, y, z;
x = y = z = 0;

That said,

Also, if I just say int a;, it seems that the value of a is zero even if it is uninitialized

It depends, if the variable has static storage duration, it will implicitly be initialized to 0.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

The answer to your fist question is "no", only the explicitly initialised variable will be assigned. The others may have any value, (including zero).

To answer your second (more interesting) question (which perhaps deserved a separate question):

The term "unitialised" simply means that no value is explicitly assigned at instantiation; the value is whatever happens to be in the associated memory location at that time. Some environments fill the stack with zero at the start of execution so in trivial examples zero is likely. It will not be true all the time however as the stack is churned over during execution, and contains different values left over from previously executed code.

For example in the following, it is likely that a in fn() will not be zero for every call (or possibly any call) and will change between calls:

void fn()
{
    static int i = 1 ;
    volatile int a ;
    printf( "Call %d: a = %d\n", i, a ) ;
    i++ ;
    a = i ;
}

int main()
{
    for( int i = 0; i < 10; i++ )
    {
        fn() ;
    }
}

In my test (at ideone.com) it output the following:

Call 1: a = 134513970
Call 2: a = 2
Call 3: a = 3
Call 4: a = 4
Call 5: a = 5
Call 6: a = 6
Call 7: a = 7
Call 8: a = 8
Call 9: a = 9
Call 10: a = 10

As you can see in the second and subsequent calls it contains whatever was left at that location from the previous call because the same stack location is reused. A different calling pattern - for example insert a function call before or after fn() will produce a different and less predictable result when that stack area is reused by other functions. For example when I modified the loop body as follows:

        rand() ;
        fn() ;

The result was:

Call 1: a = 1433091188
Call 2: a = 1433091188
Call 3: a = 1433091188
Call 4: a = 1433091188
Call 5: a = 1433091188
Call 6: a = 1433091188
Call 7: a = 1433091188
Call 8: a = 1433091188
Call 9: a = 1433091188
Call 10: a = 1433091188
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • It would be better if you mention that in such case behavior of the program could be undefined if that variable is accessed and there exist trap representation for that variable. – haccks Jan 29 '17 at 09:04
  • @haccks : I'd have to understand what your were suggesting before I could mention it! The variable is *uninitialised*, the *value* of an initialised variable is *undefined*; since all 2^32 possible values of `int` are valid, I am not sure what you mean by a "trap representation". – Clifford Jan 29 '17 at 10:32
  • @haccks : Ok - I now know what a "trap representation" is, but since I am obviously no expert I should not mention it at all. I in fact doubt that there is an implementation with such a representation for `int` despite the standard *allowing* it. I don't think the point affects the validity of the answer by omission; I am merely trying to demonstrate that one example of an unitialised variable being zero does not mean that all such variables are zero. – Clifford Jan 29 '17 at 10:41