 <p>It might be easier if you think of the comma-expression list you present like this: </p> <pre><code>((a += 3, b = c * 2), d = a + b) </code></pre> <p>First the innermost comma-expression is evaluated:</p> <pre><code>a += 3, b = c * 2 </code></pre> <p>That expression will be evaluated in two steps:</p> <pre><code>a += 3 b = c * 2 </code></pre> <p>The result of <code>a += 3</code> will be thrown away by the compiler, <em>but the assignment still happens</em>, it's just that the returned result is thrown away. The result of the first comma expression is <code>b</code> (which will be <code>c * 2</code> (whatever that is)).</p> <p>The result of the first comma expression is then on the left-hand side of the next comma expression:</p> <pre><code>b = c * 2, d = a + b </code></pre> <p>Which will then be sequenced as</p> <pre><code>b = c * 2 d = a + b </code></pre> <p>The result of the expression <code>b = c * 2</code> is thrown away (but as it is still evaluated the assignment still happens), and the result of the complete expression is <code>d</code> (which is <code>a + b</code>).</p> <p>The result of the whole expression will be <code>d</code>.</p>