Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>No, the behavior is not defined. Moreover, the code is not supposed to compile. </p> <p>Firstly, the code is not supposed to compile because it contains a constraint violation. The expression you are passing as an operand to <code>free</code> has <code>int</code> type. The parameter of <code>free</code> has <code>void *</code> type. The only case when an <code>int</code> value can be implicitly converted to <code>void *</code> type is when the <code>int</code> value is an Integral Constant Expression (ICE) with value <code>0</code>. In your case <code>x</code> is not an ICE, meaning that it is not implicitly convertible to <code>void *</code>. The only reason your code compiles is that for historical reasons (to support legacy code) your compiler quietly overlooks the constraint violation present in the <code>free(x)</code> call. I'm sure that if you elevate the level of warnings in your compiler, it will complain (at least with a warning). A pedantic compiler will immediately issue an error for <code>free(x)</code> call. Try Comeau Online, for example in C89/90 mode:</p> <pre><code>"ComeauTest.c", line 6: error: argument of type "int" is incompatible with parameter of type "void *" free(x); ^ </code></pre> <p>(Also, did you remember to include <code>stdlib.h</code> before calling <code>free</code>?)</p> <p>Secondly, let's assume that the code compiles, i.e. it is interpreted by the compiler as <code>free((void *) x)</code>. In this case a non-constant integral value <code>x</code> is converted to pointer type <code>void *</code>. The result of this conversion is implementation defined. Note, that the language guarantees that when an ICE with value of <code>0</code> is converted to pointer type, the result is a null pointer. But in your case <code>x</code> is not an ICE, so the result of the conversion is implementation-defined. In C there's no guarantee that you will obtain a null pointer by converting a non-ICE integer with value <code>0</code> to pointer type. On your implementation it probably just happened that <code>(void *) x</code> with non-ICE <code>x</code> equal to <code>0</code> produces a null pointer value of type <code>void *</code>. This null pointer value, when passed to <code>free</code>, results in a no-op, per the specification of <code>free</code>. </p> <p>In general case though, passing such a pointer to <code>free</code> will result in undefined behavior. The pointers that you can legally pass to <code>free</code> are pointers obtained by previous calls to <code>malloc</code>/<code>calloc</code>/<code>realloc</code> and null pointers. Your pointer violates this constraint in general case, so the behavior is undefined.</p> <p>This is what happens in your case. But, again, your code contains a constraint violation. And even if you override the violation, the behavior is undefined.</p> <p><strong>P.S.</strong> Note, BTW, that many answers already posted here make the same serious mistake. They assume that <code>(void *) x</code> with zero <code>x</code> is supposed to produce a null pointer. This is absolutely incorrect. Again, the language makes absolutely no guarantees about the result of <code>(void *) x</code> when <code>x</code> is not an ICE. <code>(void *) 0</code> is guaranteed to be null pointer, but <code>(void *) x</code> with zero <code>x</code> is <em>not</em> guaranteed to be null pointer.</p> <p><strong>This is covered in C FAQ</strong> <a href="http://c-faq.com/null/runtime0.html" rel="nofollow noreferrer">http://c-faq.com/null/runtime0.html</a> . For those interested in better understanding of why it is so it might be a good idea to read the entire section on null pointers <a href="http://c-faq.com/null/index.html" rel="nofollow noreferrer">http://c-faq.com/null/index.html</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload