Multiple assignment in one line

Remember that assignment is done right to left, and that they are normal expressions. So from the compilers perspective the line

sample1 = sample2 = 0;

is the same as

sample1 = (sample2 = 0);

which is the same as

sample2 = 0;
sample1 = sample2;

That is, sample2 is assigned zero, then sample1 is assigned the value of sample2. In practice the same as assigning both to zero as you guessed.


Formally, for two variables t and u of type T and U respectively

T t;
U u;

the assignment

t = u = X;

(where X is some value) is interpreted as

t = (u = X);

and is equivalent to a pair of independent assignments

u = X;
t = (U) X;

Note that the value of X is supposed to reach variable t "as if" it has passed through variable u first, but there's no requirement for it to literally happen that way. X simply has to get converted to type of u before being assigned to t. The value does not have to be assigned to u first and then copied from u to t. The above two assignments are actually not sequenced and can happen in any order, meaning that

t = (U) X;
u = X;

is also a valid execution schedule for this expression. (Note that this sequencing freedom is specific to C language, in which the result of an assignment in an rvalue. In C++ assignment evaluates to an lvalue, which requires "chained" assignments to be sequenced.)

There's no way to say whether it is a good or bad programming practice without seeing more context. In cases when the two variables are tightly related (like x and y coordinate of a point), setting them to some common value using "chained" assignment is actually perfectly good practice (I'd even say "recommended practice"). But when the variables are completely unrelated, then mixing them in a single "chained" assignment is definitely not a good idea. Especially if these variables have different types, which can lead to unintended consequences.


I think there is no good answer on C language without actual assembly listing :)

So for a simplistic program:

int main() {
        int a, b, c, d;
        a = b = c = d = 0;
        return a;
}

I've got this assemly (Kubuntu, gcc 4.8.2, x86_64) with -O0 option of course ;)

main:
        pushq   %rbp
        movq    %rsp, %rbp

        movl    $0, -16(%rbp)       ; d = 0
        movl    -16(%rbp), %eax     ; 

        movl    %eax, -12(%rbp)     ; c = d
        movl    -12(%rbp), %eax     ;

        movl    %eax, -8(%rbp)      ; b = c
        movl    -8(%rbp), %eax      ;

        movl    %eax, -4(%rbp)      ; a = b
        movl    -4(%rbp), %eax      ;

        popq    %rbp

        ret                         ; return %eax, ie. a

So gcc is actually chaining all the stuff.


You can yourself decide that this way of coding is good or bad.

  1. Simply see the assembly code for the following lines in your IDE.

  2. Then change the code to two separate assignments, and see the differences.

In addition to this, you can also try turning off/on optimizations (both Size & Speed Optimizations) in your compiler to see how that affects the assembly code.