title: In the comma operator, is the left operand guaranteed not to be actually executed if it hasn't side effects?
body: <p>To show the topic I'm going to use C, but the same macro can be used also in C++ (with or without <code>struct</code>), raising the same question.</p>
  
  <p>I came up with this macro</p>
  
  <pre><code>#define STR_MEMBER(S,X) (((struct S*)NULL)-&gt;X, #X)
  </code></pre>
  
  <p>Its purpose is to have strings (<code>const char*</code>) of an existing member of a <code>struct</code>, so that if the member doesn't exist, the compilation fails. A minimal usage example:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  struct a
  {
      int value;
  };
  
  int main(void)
  {
      printf("a.%s member really exists\n", STR_MEMBER(a, value));
      return 0;
  }
  </code></pre>
  
  <p>If <code>value</code> weren't a member of <code>struct a</code>, the code wouldn't compile, and this is what I wanted.</p>
  
  <p>The comma operator should evaluate the left operand and then discard the result of the expression (if there is one), so that my understanding is that usually this operator is used when the evaluation of the left operand has side effects.</p>
  
  <p>In this case, however, there aren't (intended) side effects, but of course it works <em>iff</em> the compiler doesn't actually produce the code which evaluates the expression, for otherwise it would access to a <code>struct</code> located at <code>NULL</code> and a <em>segmentation fault</em> would occur.</p>
  
  <p>Gcc/g++ 6.3 and 4.9.2 never produced that dangerous code, even with <code>-O0</code>, as if they were always able to “see” that the evaluation hasn't side effects and so it can be skipped.</p>
  
  <p>Adding <code>volatile</code> in the macro (e.g. because accessing that memory address <em>is</em> the desired side effect) was so far the only way to trigger the segmentation fault.</p>
  
  <p>So the question: <strong>is there anything in the C and C++ languages standard which guarantees that compilers will always avoid actual evaluation of the left operand of the comma operator when the compiler can be sure that the evaluation hasn't side effects?</strong></p>
  
  <h2>Notes and fixing</h2>
  
  <p>I am not asking for a judgment about the macro <em>as it is</em> and the opportunity to use it or make it better. For the purpose of this question, the macro is bad <em>if and only if</em> it evokes undefined behaviour — i.e., <em>if and only if</em> it is risky because compilers are allowed to generate the “evaluation code” even when this hasn't side effects.</p>
  
  <p>I have already two obvious fixes in mind: “reifying” the <code>struct</code> and using <code>offsetof</code>. The former needs an accessible memory area as big as the biggest <code>struct</code> we use as first argument of <code>STR_MEMBER</code> (e.g. maybe a static union could do…). The latter should work flawlessly: it gives an offset we aren't interested in and avoids the access problem — indeed I'm assuming <em>gcc</em>, because it's the compiler I use (hence the tag), and that its <code>offsetof</code> built-in behaves.</p>
  
  <p>With the <code>offsetof</code> fix the macro becomes</p>
  
  <pre><code>#define STR_MEMBER(S,X) (offsetof(struct S,X), #X)
  </code></pre>
  
  <p>Writing <code>volatile struct S</code> instead of <code>struct S</code> doesn't cause the segfault.</p>
  
  <p>Suggestions about other possible “fixes” are welcome, too.</p>
  
  <h2>Added note</h2>
  
  <p>Actually, the real usage case was in C++ in a static storage <code>struct</code>. This seems to be fine in C++, but as soon as I tried C with a code closer to the original instead of the one boiled for this question, I realized that C isn't happy at all with that:</p>
  
  <pre><code>error: initializer element is not constant
  </code></pre>
  
  <p>C wants the struct to be initializable at compile time, instead C++ it's fine with that.</p>